[PGSQL] Werktijden opslaan
Heey allemaal,
Ik vroeg me af wat nou de beste manier is om de werktijden van iemand op te slaan. Er zijn nogal wat voorwaarden die ingecalculeerd moeten worden:
- Iemand kan op verschillende dagen van de week op verschillende tijden werken, maar wel iedere week hetzelfde.
- Iemand heeft pauzes waarop niet gewerkt wordt
- Iemand kan een dag of week vrijnemen
- Iemand kan een doktersafspraak hebben waardoor hij een half uur of uur of whatever niet kan werken
Dus wat is nou een ideale manier van werktijden opslaan zodat er gemakkelijk wijzigingen toegevoegd kunnen worden?
Groet
Newb
Ik vroeg me af wat nou de beste manier is om de werktijden van iemand op te slaan. Er zijn nogal wat voorwaarden die ingecalculeerd moeten worden:
- Iemand kan op verschillende dagen van de week op verschillende tijden werken, maar wel iedere week hetzelfde.
- Iemand heeft pauzes waarop niet gewerkt wordt
- Iemand kan een dag of week vrijnemen
- Iemand kan een doktersafspraak hebben waardoor hij een half uur of uur of whatever niet kan werken
Dus wat is nou een ideale manier van werktijden opslaan zodat er gemakkelijk wijzigingen toegevoegd kunnen worden?
Groet
Newb
Ik zou de tijden niet loggen, alleen de gemaakte uren. Dan ben je er al. Per werknemer stel je in hoeveel uur per week gemaakt moeten worden; bij het vrijgeven door de gebruiker check je of de werknemer zijn minimale aantal uur heeft gemaakt.
Gewijzigd op 01/01/1970 01:00:00 door Pim Vernooij
In de database zou ik puur de tijden opslaan waarop iemand daadwerkelijk aan het werk is. Dus gebruik een TIMESTAMP veld voor zowel de begin- als eindtijd.
Net als het principe van in- en uitklokken: een werknemer begint met werken en registreert zijn begintijd (klokt in), vervolgens gaat hij naar de tandarts en registreert zijn eindtijd (klokt uit). Komt hij weer terug, herhaalt dit proces zich totdat de werknemer uiteindelijk weer naar huis gaat...
Net als het principe van in- en uitklokken: een werknemer begint met werken en registreert zijn begintijd (klokt in), vervolgens gaat hij naar de tandarts en registreert zijn eindtijd (klokt uit). Komt hij weer terug, herhaalt dit proces zich totdat de werknemer uiteindelijk weer naar huis gaat...
Ik zal de tijden wel moeten loggen. Het is namelijk de bedoeling dat mensen afspraken kunnen maken met de mensen die op dat moment aan het werk zijn.
edit:
En de een werkt dus van 8 tot 5, een ander van 9 tot 6. Een derde heeft weer een vrije dag op vrijdag, een vierde werkt maar partime en een vijfde heeft m de week een vrije dag. Dit zal dus allemaal in het systeem moeten komen zodat mensen zien wie wanneer aan het werk is.
Gewijzigd op 01/01/1970 01:00:00 door PHP Newbie
Ik zou vrije dagen sowieso in een andere tabel opslaan. Dan kan je ook makkelijk zien hoeveel vrije dagen iemand al heeft opgenomen ed.
De rest zou ik zo doen:
id | persoon_id | begintijd | eindtijd | datum
Begintijd en eindtijd zijn dan time-velden en de datum is een date veld.
Als iemand iedere week de zelfde dagen werkt dan kan dat ook. Ook als iemand niet elke dag hetzelfde werkt. Op deze manier is alles mogelijk.
Je zou natuurlijk nog een extra tabel kunnen makne met standaard tijden van werknemers (per dag). En dan zou je die automatisch in bovenstaande tabel kunnen laten zetten, maar dat is eigelijk allen een handige functie voor de gebruiker.
De rest zou ik zo doen:
id | persoon_id | begintijd | eindtijd | datum
Begintijd en eindtijd zijn dan time-velden en de datum is een date veld.
Als iemand iedere week de zelfde dagen werkt dan kan dat ook. Ook als iemand niet elke dag hetzelfde werkt. Op deze manier is alles mogelijk.
Je zou natuurlijk nog een extra tabel kunnen makne met standaard tijden van werknemers (per dag). En dan zou je die automatisch in bovenstaande tabel kunnen laten zetten, maar dat is eigelijk allen een handige functie voor de gebruiker.
1000 werknemers, 300 werkdagen. Minimaal 2 pauze op een dag waardoor er sowiso 2 records per dag nodig zijn.
600.000 records. Als we daar nog flink mee moeten gaan rekenen om de juiste gegevens op het scherm te krijgen is dat natuurlijk wel een flinke aanslag op de server.
Begintijd en eindtijd kunnen trouwens gewoon datetime velden zijn in je voorbeeld. Heb je die kolom "datum" niet meer nodig. Alleen maar onhandig.
Maar ik vraag me toch af of er geen gemakkelijkere oplossing is dan dit. Hoeveel vrije dagen iemand heeft opgenomen boeit me niet en zal me ook niet boeien. Het gaat mij er alleen om wanneer iemand werkt.
600.000 records. Als we daar nog flink mee moeten gaan rekenen om de juiste gegevens op het scherm te krijgen is dat natuurlijk wel een flinke aanslag op de server.
Begintijd en eindtijd kunnen trouwens gewoon datetime velden zijn in je voorbeeld. Heb je die kolom "datum" niet meer nodig. Alleen maar onhandig.
Maar ik vraag me toch af of er geen gemakkelijkere oplossing is dan dit. Hoeveel vrije dagen iemand heeft opgenomen boeit me niet en zal me ook niet boeien. Het gaat mij er alleen om wanneer iemand werkt.
Pauzes vermeld je (uiteraard) niet, want die horen bij de werktijden.
En ik neem aan dat je dit VOORAF wil weten. Dus niet wil zien OF iemand er ook daadwerkelijk was. Immers: het gaat om afspraken (in de toekomst) maken en niet in het verleden.
Mijn idee hierbij:
- tabel PERSONEN (uiteraard)
- tabel WERK daarin: dag+persoon+start-tijd+eind-tijd
- tabel VRIJ (vrij/dokter/vakantie) met daarin: persoon + start (datetime) + eind (datetime).
Het is wordt was SQL-en, maar dat is geen probleem.
Met BETWEEN (start/eind) kan je heel veel.
Je kan dan van iedere seconde/minuut/dag opvragen welke personen er zijn
Tip: voor dit soort rekenwerk gebruik je dus VIEWS.
1x per dag de moeilijke query uitvoeren en klaar.
Ziekmeldingen (ter plaatse op het werk/tijdens het werk) kan je natuurlijk niets aan doen.
En ik neem aan dat je dit VOORAF wil weten. Dus niet wil zien OF iemand er ook daadwerkelijk was. Immers: het gaat om afspraken (in de toekomst) maken en niet in het verleden.
Mijn idee hierbij:
- tabel PERSONEN (uiteraard)
- tabel WERK daarin: dag+persoon+start-tijd+eind-tijd
- tabel VRIJ (vrij/dokter/vakantie) met daarin: persoon + start (datetime) + eind (datetime).
Het is wordt was SQL-en, maar dat is geen probleem.
Met BETWEEN (start/eind) kan je heel veel.
Je kan dan van iedere seconde/minuut/dag opvragen welke personen er zijn
Tip: voor dit soort rekenwerk gebruik je dus VIEWS.
1x per dag de moeilijke query uitvoeren en klaar.
Ziekmeldingen (ter plaatse op het werk/tijdens het werk) kan je natuurlijk niets aan doen.
He Newbie
Ik zou gaan werken met dagen waarop iemand werkt, dwz de werkdagen. Tevens zou ik van een persoon tijdblokken opnemen waarop hij of zij beschikbaar is. Een tijdblok is bijv 6 minuten. Nu kun je vanaf starttijd == winkel open de tijdblokken tellen tot aan begin_pauze en vanaf eind_pauze tot winkel dicht. Uiteraard als iemand parttime werkt alleen bij tot aan begin_pauze.
Ik heb hier al eens een discussie over gahd op Phpfreakz en ben tot de conclusie gekomen dat dit de handigste methode is.
groeten
Klaasjan
edit
Uiteraard zijn de tijdblokken ook een mooi begin voor de opbouw van de werksoorten. Elke werksoort duurt X tijdblokken.
Uiteraard pre fill je dit voor jaren en alleen de uitzonderingen haal je weg.
Een dag vrij betekend gewoon in die dag een werkdag minder. Een half uur naar de dokter betekend op die dag 5 tijdsblokken minder. en ja dat alles bijhouden tijd kost is waar maar dat kost het in de analoge wereld ook.
Ik begrijp dat je druk bezig bent?
Hoe was het gisteravond?
Ik zou gaan werken met dagen waarop iemand werkt, dwz de werkdagen. Tevens zou ik van een persoon tijdblokken opnemen waarop hij of zij beschikbaar is. Een tijdblok is bijv 6 minuten. Nu kun je vanaf starttijd == winkel open de tijdblokken tellen tot aan begin_pauze en vanaf eind_pauze tot winkel dicht. Uiteraard als iemand parttime werkt alleen bij tot aan begin_pauze.
Ik heb hier al eens een discussie over gahd op Phpfreakz en ben tot de conclusie gekomen dat dit de handigste methode is.
groeten
Klaasjan
edit
Uiteraard zijn de tijdblokken ook een mooi begin voor de opbouw van de werksoorten. Elke werksoort duurt X tijdblokken.
Uiteraard pre fill je dit voor jaren en alleen de uitzonderingen haal je weg.
Een dag vrij betekend gewoon in die dag een werkdag minder. Een half uur naar de dokter betekend op die dag 5 tijdsblokken minder. en ja dat alles bijhouden tijd kost is waar maar dat kost het in de analoge wereld ook.
Ik begrijp dat je druk bezig bent?
Hoe was het gisteravond?
Gewijzigd op 01/01/1970 01:00:00 door Klaasjan Boven
Ik heb dit topic vooral geopend om eens te kijken hoe anderen hier tegenaan kijken. Ik had zelf ook wel een idee (te vergelijken met Citroen), maar ik wilde graag weten of er nog andere oplossingen zijn die gemakkelijker of minder belastend zijn.
@Klaasjan
Tijdblokken.. tsjah.. dan ben je toch weer gebonden aan (in jouw voorbeeld) 6 minuten (zou dan eerder voor 5 minuten gaan, maar dat terzijde). Het kan wel, maar dat vind ik toch niet een ideale situatie.
Wanneer er nog meer ideeën zijn hoor ik ze natuurlijk graag!
@Klaasjan
Tijdblokken.. tsjah.. dan ben je toch weer gebonden aan (in jouw voorbeeld) 6 minuten (zou dan eerder voor 5 minuten gaan, maar dat terzijde). Het kan wel, maar dat vind ik toch niet een ideale situatie.
Wanneer er nog meer ideeën zijn hoor ik ze natuurlijk graag!
In principe kan je ook een tabel met aanwezigheid maken, waarin je de standaard werktijden aangeeft en een tabel met afwezigheid, waarin je aangeeft welke dagen/ tijden iemand niet aanwezig is. Dit is ook eenvoudig te combineren met reeds gemaakte afspraken (geldt ook eigenlijk als afwezigheid, omdat je niet 2 mensen tegelijk kan helpen)
Zo kan je vrij eenvoudig en simpel zien op welke dagen iemand aanwezig zou (moeten) zijn en of deze persoon ook tijd heeft.
Zo kan je vrij eenvoudig en simpel zien op welke dagen iemand aanwezig zou (moeten) zijn en of deze persoon ook tijd heeft.
Ik zit nu hieraan te denken:
Werkdagen
medewerkerid | maandag_van | maandag_tot | dinsdag_van | ... | zondag_tot
Vrije perioden
medewerkerid | van | tot
Afspraken
medewerkerid | van | tot
Ja, de afspraken moeten apart van de vrije perioden opgeslagen worden want deze moeten op een andere manier weergeven worden.
"van" en "tot" is gewoon een datetime veld en kan dus een uur tot (bij wijze van) 100 jaar duren.
*_van en *_tot zijn TIME fields
Wat vinden jullie van deze opzet?
Werkdagen
medewerkerid | maandag_van | maandag_tot | dinsdag_van | ... | zondag_tot
Vrije perioden
medewerkerid | van | tot
Afspraken
medewerkerid | van | tot
Ja, de afspraken moeten apart van de vrije perioden opgeslagen worden want deze moeten op een andere manier weergeven worden.
"van" en "tot" is gewoon een datetime veld en kan dus een uur tot (bij wijze van) 100 jaar duren.
*_van en *_tot zijn TIME fields
Wat vinden jullie van deze opzet?
Gewijzigd op 01/01/1970 01:00:00 door PHP Newbie
@PHP Newbie
Ik zou het anders doen, om eenvoudiger te kunnen vergelijken, in de tabel werkdagen en ook vollediger genormaliseerd:
id | medewerkerid | dagnr | van | tot |
Het dagnr is hetzelfde als wat je bij weekday() eruit krijgt (is eenvoudig te vergelijken dan) en van en tot zijn gewoon tijden.
Je kijkt bij een datum 'gewoon' welke dag het is dat een afspraak gemaakt zal gaan worden. Dan kijk je welke medewerkers er op die dag zijn, en of ze geen vrije periode of afspraken hebben. Dat is vrij eenvoudig te realiseren.
De weergave van vrije perioden en afspraken is GEEN reden om deze in een losse tabel te zetten, door een kolom toe te voegen (type) in de tabel voor 'bezette_tijden' in dit geval, kan je heel eenvoudig aangeven of het een afspraak is, of het een vrije periode is, of bedenk het maar.
Uitbreiden is dan eenvoudiger (eventueel koppel je er nog een tabel bezet_typen aan, waarin je de naam/ omschrijving van het type zet) te doen, stel dat je later ook nog de reden van een vrije periode wil toevoegen o.i.d. Dan is dat met deze opzet heel eenvoudig.
Weergave is nooit een reden om nieuwe tabellen te maken!
Ik zou het anders doen, om eenvoudiger te kunnen vergelijken, in de tabel werkdagen en ook vollediger genormaliseerd:
id | medewerkerid | dagnr | van | tot |
Het dagnr is hetzelfde als wat je bij weekday() eruit krijgt (is eenvoudig te vergelijken dan) en van en tot zijn gewoon tijden.
Je kijkt bij een datum 'gewoon' welke dag het is dat een afspraak gemaakt zal gaan worden. Dan kijk je welke medewerkers er op die dag zijn, en of ze geen vrije periode of afspraken hebben. Dat is vrij eenvoudig te realiseren.
De weergave van vrije perioden en afspraken is GEEN reden om deze in een losse tabel te zetten, door een kolom toe te voegen (type) in de tabel voor 'bezette_tijden' in dit geval, kan je heel eenvoudig aangeven of het een afspraak is, of het een vrije periode is, of bedenk het maar.
Uitbreiden is dan eenvoudiger (eventueel koppel je er nog een tabel bezet_typen aan, waarin je de naam/ omschrijving van het type zet) te doen, stel dat je later ook nog de reden van een vrije periode wil toevoegen o.i.d. Dan is dat met deze opzet heel eenvoudig.
Weergave is nooit een reden om nieuwe tabellen te maken!
@Robert:
Ook die kolom dagnr is overbodig. Als je voor de kolommen 'van' en 'tot' gewoon datetime velden maakt, zit de dag er al in verwerkt. Meer dan een datetime heb je niet nodig.
Verder zou ik voor de opzet van Eddy gaan, waarbij je de 'vrij' tabel nog verder uit kunt breiden met een kolom die aangeeft waarom iemand vrij is...
ps. Zoals jij dus ook al zei Robert ;-)
Ook die kolom dagnr is overbodig. Als je voor de kolommen 'van' en 'tot' gewoon datetime velden maakt, zit de dag er al in verwerkt. Meer dan een datetime heb je niet nodig.
Verder zou ik voor de opzet van Eddy gaan, waarbij je de 'vrij' tabel nog verder uit kunt breiden met een kolom die aangeeft waarom iemand vrij is...
ps. Zoals jij dus ook al zei Robert ;-)
Gewijzigd op 01/01/1970 01:00:00 door Joren de Wit
@blanche, dagnummer zal wel genoteerd moeten worden aangezien het iedere maandag hetzelfde is toch?
@Blanche
Dat snap ik, maar het ging mij er eigenlijk om dat je voor een bepaalde dag meteen van een werknemer voor het hele jaar aangeeft dat die op die dag werkt, volgens mij kan je dan net zo goed of zelf beter met dagnummer gaan werken.
Eigenlijk wat PHP Newbie ook zegt, die zou je normaal gesproken bij zo'n werking van een systeem wel gebruiken.
Dat snap ik, maar het ging mij er eigenlijk om dat je voor een bepaalde dag meteen van een werknemer voor het hele jaar aangeeft dat die op die dag werkt, volgens mij kan je dan net zo goed of zelf beter met dagnummer gaan werken.
Eigenlijk wat PHP Newbie ook zegt, die zou je normaal gesproken bij zo'n werking van een systeem wel gebruiken.
'edit':
@PHP Newbie
Overigens kan je de tabel met werktijden nog uitbreiden met een kolom 'herhaalperiode'. In deze kolom kan je bijvoorbeeld met het getal 1 aangeven dat het elke week op die dag is, en met het getal 2 dat dit maar eens in de 2 weken voorkomt.
Zeker bij grotere organisaties komen deze constructies nog wel eens voor.
Overigens kan je de tabel met werktijden nog uitbreiden met een kolom 'herhaalperiode'. In deze kolom kan je bijvoorbeeld met het getal 1 aangeven dat het elke week op die dag is, en met het getal 2 dat dit maar eens in de 2 weken voorkomt.
Zeker bij grotere organisaties komen deze constructies nog wel eens voor.
Gewijzigd op 01/01/1970 01:00:00 door Robert Deiman
That depends. Voor een werknemer met een 40 uurs werkweek en vaste werktijden waarschijnlijk wel. Maar voor freelancers, part-timers met flexibele uren, enz. zal dat zeker niet gelden.
In dat laatste geval heeft het opslaan van het dagnummer zeker geen nut en heb je veel maar aan een datumtijdstempel.
In dat laatste geval heeft het opslaan van het dagnummer zeker geen nut en heb je veel maar aan een datumtijdstempel.
@Blanche
'PHP:
- Iemand kan op verschillende dagen van de week op verschillende tijden werken, maar wel iedere week hetzelfde.
- Iemand heeft pauzes waarop niet gewerkt wordt
- Iemand kan een dag of week vrijnemen
- Iemand kan een doktersafspraak hebben waardoor hij een half uur of uur of whatever niet kan werken
- Iemand heeft pauzes waarop niet gewerkt wordt
- Iemand kan een dag of week vrijnemen
- Iemand kan een doktersafspraak hebben waardoor hij een half uur of uur of whatever niet kan werken
'edit':
Verder heb je wel gelijk, maar dat kan je oplossen door een keuze te laten in je tabel:
dagnummer | datum
Vul je dagnummer in, weet je dat het over een vaste medewerker met vaste dagen gaat, maar vul je een datum in (laat je dus dagnummer leeg) dan weet je dat het om een parttimer gaat, waarvoor je de data invult.
Een afspraak wordt altijd op een bepaalde datum gepland, door EN te kijken of er parttimers zijn die op die bepaalde datum werken EN te kijken welke dag die datum valt en welke vaste medewerkers er dan zijn (en welke medewerkers nog geen afspraak hebben) heb je alles wat je weten wilt.
Zo hou je de boel wel heel flexibel.
dagnummer | datum
Vul je dagnummer in, weet je dat het over een vaste medewerker met vaste dagen gaat, maar vul je een datum in (laat je dus dagnummer leeg) dan weet je dat het om een parttimer gaat, waarvoor je de data invult.
Een afspraak wordt altijd op een bepaalde datum gepland, door EN te kijken of er parttimers zijn die op die bepaalde datum werken EN te kijken welke dag die datum valt en welke vaste medewerkers er dan zijn (en welke medewerkers nog geen afspraak hebben) heb je alles wat je weten wilt.
Zo hou je de boel wel heel flexibel.
Gewijzigd op 01/01/1970 01:00:00 door Robert Deiman
Heb je gelijk in Robert, lijkt mij een mooie oplossing die je nu aandraagt ;-)
Of nog een betere optie:
Wel een datum invullen, gewoon op het moment dat je begint met invullen de 1e 5 werkdagen inladen (dus te beginnen bij de 1e volgende werkdag, dus waar dag gelijk is aan of maandag, of dinsdag... enz.) en daarvan de datum in de database zetten.
Door dan een kolom "medewerkerstype" toe te voegen kan je aangeven of het om een parttimer gaat of om een vaste medewerker. Bij een vaste medewerker kan je van die datum ook zien welke dag het is. Is (denk ik) wel minder snel, maar het is eenvoudiger om nog eventueel andere typen medewerkers/ roosteringen te maken.
Wel een datum invullen, gewoon op het moment dat je begint met invullen de 1e 5 werkdagen inladen (dus te beginnen bij de 1e volgende werkdag, dus waar dag gelijk is aan of maandag, of dinsdag... enz.) en daarvan de datum in de database zetten.
Door dan een kolom "medewerkerstype" toe te voegen kan je aangeven of het om een parttimer gaat of om een vaste medewerker. Bij een vaste medewerker kan je van die datum ook zien welke dag het is. Is (denk ik) wel minder snel, maar het is eenvoudiger om nog eventueel andere typen medewerkers/ roosteringen te maken.
'edit':
Ik denk wel dat dit niet handig werken is, misschien is het wel een handige optie om bij medewerkers (de vaste) een startdatum op te geven. Wanneer iemand wordt aangenomen begint deze vaak niet per direct,maar je kan dan wel van tevoren al zijn/ haar rooster erin plaatsen.
Gewijzigd op 01/01/1970 01:00:00 door Robert Deiman
toch even mijn ideetje erin gooien...
waarom werk je niet met een soort log?
net zoals Blanche zei in het begin van deze topic maar dan doe je:
Insert into logs (werknemer, start) values.....blabla
wanneer hij dan uitlogt vergelijk je de tijd van uitloggen met die 'start', het verschil daartussen sla je op in je tabel 'werktijd per wn' of zoiets...
ik neem aan dat als je afspraken hebt e.d. dat die vooraf moeten worden aangevraagd of iets dus je krijgt een tabel: afspraken...hierin staat dan wanneer de afspraak is en wanneer hij eindigt.
dit kan je dan meteen ook aftrekken van die start....
het is maar een ideetje...
waarom werk je niet met een soort log?
net zoals Blanche zei in het begin van deze topic maar dan doe je:
Insert into logs (werknemer, start) values.....blabla
wanneer hij dan uitlogt vergelijk je de tijd van uitloggen met die 'start', het verschil daartussen sla je op in je tabel 'werktijd per wn' of zoiets...
ik neem aan dat als je afspraken hebt e.d. dat die vooraf moeten worden aangevraagd of iets dus je krijgt een tabel: afspraken...hierin staat dan wanneer de afspraak is en wanneer hij eindigt.
dit kan je dan meteen ook aftrekken van die start....
het is maar een ideetje...
@Tikkes
Zoals al aangegeven was het de bedoeling dat medewerkers wekelijks dezelfde tijden werken. Daarnaast wil het niet zeggen dat als iemand geen afspraak heeft dat dit betekend dat iemand vrij is.
Ik denk dat laatstgenoemde optie de meeste voordelen heeft.
Zoals al aangegeven was het de bedoeling dat medewerkers wekelijks dezelfde tijden werken. Daarnaast wil het niet zeggen dat als iemand geen afspraak heeft dat dit betekend dat iemand vrij is.
Ik denk dat laatstgenoemde optie de meeste voordelen heeft.




