[PGSQL] Werktijden opslaan
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
Gewijzigd op 01/01/1970 01:00:00 door Pim Vernooij
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...
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
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.
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.
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.
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
@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!
Zo kan je vrij eenvoudig en simpel zien op welke dagen iemand aanwezig zou (moeten) zijn en of deze persoon ook tijd heeft.
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
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!
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?
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
In dat laatste geval heeft het opslaan van het dagnummer zeker geen nut en heb je veel maar aan een datumtijdstempel.
PHP Newbie:
- 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 ;-)
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
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...
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.