MirusMentis Skrevet 24. september 2007 Del Skrevet 24. september 2007 Tenkte jeg skulle lage et booking system for firmabilene vi har på jobben. -Jeg vil ha mulighet til å velge hvem av de 2 bilene jeg vil booke. -Mulighet til å se "kalenderen" for hver bil både frem og tilbake i tid. -Trenger ikke en fancy "date picker" det holder med en dropdown for dag,mnd og år. Jeg er rimelig fersk på pgp/mysql, så jeg klarer ikke helt å tenke meg frem til en mest mulig logisk db struktur.. Hvordan høres dette ut: En tabel den har følgende felt: id, regnr, starttid, slutttid, sjåfør. forklaring: id: greit å ha et tall på hver rad har jeg lært. regnr: for å adskille de 2 bilene. Mulig dette feltet kunne vært sløyfet og heller hatt en tabell for hver bil..? tips? starttid: når reserveringen begynner sluttid: når den ender sjåfør: hvem som har brukt bilen, verdien til dette feltet er planlagt å komme fra Session, da jeg påsikt vil ha innlogging. I utganspunktet er det ikke kodingen jeg vil ha hjelp til, det skal jeg nok klare selv, jeg trenger kun en vurdering på strukturen.. ser den grei ut? Ville du gjort det annerledes? Spesielt med tanke på et felt for hvilken bil, eller om jeg skal ha en tabell for hver bil.. Edit: kom på at det hadde vært fint å kunne slått opp på en gitt dato og så sjekke om bilen er ledig. Hadde også vært greit å hatt en slags kontroll på at de ikke blir dobbeltbooket.. Men dette krever nok en fullverdig kalender funksjon, ikke en "tekstbasert" som jeg hadde planer om.. Lenke til kommentar
Ståle Skrevet 25. september 2007 Del Skrevet 25. september 2007 Dette er nesten bare SQL, sa kanskje den burde ligget i Database kategorien. Jeg ville kjort alt i en tabell. Da trenger du ikke tenke pa a joine de to tabellene nar du skal liste opp om den er ledig. Derimot ma du huske WHERE regnr="313" nar du bare skal liste den ene bilen. Hvordan a lage dobbelbook-funksjonen var litt vanskelig. Men hvorfor skulle ikke det ga med en tekstbasertkalender? et lite AJAX-script som sjekker om tiden er ledig mens man skriver inn verdier. Men selve scriptet.. hmm.. vanskelig.. skal tenke litt pa det. Lenke til kommentar
Runar0 Skrevet 25. september 2007 Del Skrevet 25. september 2007 CREATE TABLE IF NOT EXISTS `bookings` ( `id` int(11) NOT NULL auto_increment, `car_id` int(11) NOT NULL default '0', `starttime` datetime NOT NULL default '0000-00-00 00:00:00', `endtime` datetime NOT NULL default '0000-00-00 00:00:00', `driver` varchar(32) NOT NULL default '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `cars` ( `id` int(11) NOT NULL auto_increment, `regnumber` varchar(30) NOT NULL default '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; Dette er nok måten eg hadde løst problemet på. I tabellen cars lister du opp alle bilane (Du bruker inner join booking.car_id = car.id for å hente informasjon om bilen i lag med utleige tidene), mens i tabellen bookings har du alle utleige tidene. Som du ser så har eg satt driver til varchar, denne kan godt vere driver_id og innehalde iden til brukaren som skal bruke bilen (vist du har alle brukarane i ei database) Bare eit lite tips fra meg * Denne hører nok heime i database forumet * Lenke til kommentar
MirusMentis Skrevet 25. september 2007 Forfatter Del Skrevet 25. september 2007 Takker for svar.. Jeg har vel sittet 8-9timer med dette nå, og kommet frem til at jeg sløyfer sjekk for dobbeltbooking.. Jeg bruker nå kalender scriptet til Zorac herifra: https://www.diskusjon.no/index.php?showtopi...t=0&p=7925437 Dette gir meg år, mnd og dag som jeg setter sammen til f.eks 25-09-2007 og lagrer som varchar dato i basen. starttid og slutttid må bruker selv oppgi som tekst. Se eksempel her: http://pyrabel.net/dgi akkurat nå har jeg ikke noe loginsystem ferdig, så de taster inn navnet i en tekstbok, men endrer dette til brukerid bare jeg får laget en tabell for brukere. Lenke til kommentar
ZoRaC Skrevet 25. september 2007 Del Skrevet 25. september 2007 Hvis du lagrer tid som unix-timestamp i stedet, så vil kalenderscriptet "markere" de dagene hvor det ligger noe inne. Kan være greit å se på kalenderen når biler er ledig/opptatt? Lenke til kommentar
MirusMentis Skrevet 26. september 2007 Forfatter Del Skrevet 26. september 2007 Hvis du lagrer tid som unix-timestamp i stedet, så vil kalenderscriptet "markere" de dagene hvor det ligger noe inne. Kan være greit å se på kalenderen når biler er ledig/opptatt? 9576650[/snapback] Var det jeg prøvde på men fant ikke noe dokumentasjon på hvordan jeg skulle bruke det.. Kan fortsatt se når den er ledig.. Kalenderen gir $dato = dd-mm-åå, så kjører jeg en sql spørring og sjekker om det ligger noe inne der dato feltet = $dato Hvordan kan jeg lagre tidspunktet som unix timestamp? Må disse feltene i databasen være 'datetime' da? Nå er det VARCHAR.. Lenke til kommentar
Runar0 Skrevet 26. september 2007 Del Skrevet 26. september 2007 Nei, skal du lagre eit unix_timestamp så passer int(11) best Lenke til kommentar
MirusMentis Skrevet 26. september 2007 Forfatter Del Skrevet 26. september 2007 I fare for å virke direkte dum/lat så understreker jeg at jeg faktisk har søkt før jeg skriver dette. Unix timestamp; Hvordan kan jeg lage et enkelt interface/gui som lar brukeren velge start tid og slutt tid slik at scriptet mitt kan lage et timestamp ut av det? De klikker på en dag i kalenderen, og url`n blir da side.php?yr=07&mn=09&dd=26 Så langt har vi år, måned og dag i hver sin variabel. -So far so good. Nå skal brukeren fylle ut en form der han velger hvilken bil, og skriver en kort beskrivelse av formål med reise, samt klokkeslett for start og slutt. Formen har jeg laget, alt fungerer, men hvordan skal jeg nå "merge" dato,mnd,år med det brukeren taster inn som start/slutt ? slik det er nå lagrerg jeg dato i et feltt (dd-mm-åå) og så setter jeg sammen start og slutt til en tekststreng (hh:mm - hh:mm) og legger dette i et felt i basen som jeg kaller "tidsrom" Dette fungerer i grunn greit, men jeg har ikke mulighet til å sjekke for dobbeltbooking/ledig tid.. Kunne noen hjulpet meg med å skrive dette om til å bruke unix timestamps (eller andre metoder hvis det finnes noe lettere) og hjelpe meg med å lage en kontroll for å sjekke at man ikke "leier" ut bilene til 2 stk på samme tid. Lenke til kommentar
Runar0 Skrevet 26. september 2007 Del Skrevet 26. september 2007 Du kan lage to tekst strenger med dato og tid (start i den eine og slutt i den andre) og bruke strtotime() for å konvertere den til eit unix timestamp. Lenke til kommentar
ZoRaC Skrevet 26. september 2007 Del Skrevet 26. september 2007 www.php.net/mktime <--- sett inn time, minutter, dag, måned og år på "rett sted" og du får et unix-timestamp tilbake. Lenke til kommentar
MirusMentis Skrevet 26. september 2007 Forfatter Del Skrevet 26. september 2007 Ok så hvis $dato = "26.09.07" og $start = "10:30" kan jeg da lage timestamp med denne kommandoen: $timestamp = $dato . $start $timestamp = strtotime($timestamp); Vil det fungere? Så må jeg lage til svarende med slutttid. Da har jeg to timestamps. Hvordan kan jeg nå sjekke at en bruker ikke forsøker å registrere en bil på et tidspunkt mellom disse timestamps? Lenke til kommentar
MirusMentis Skrevet 27. september 2007 Forfatter Del Skrevet 27. september 2007 (endret) Har fått laget timestamp for start og slutt av hver reservasjon nå, dette legges i hvert sitt felt i tabellen. slik: $start_stamp = mktime($start_time,$start_minutt,NULL,$mn,$day,$yr); $slutt_stamp = mktime($slutt_time,$slutt_minutt,NULL,$mn,$day,$yr); Hvordan kan jeg nå ved neste registrering sjekke at ønsket tid ikke interferer med en allerede registrert reservasjon? Jeg har tenkt på følgende: //Finner alle reservasjoner for angitt dato mysql_select_db("pyrabel_basenmin") or die(mysql_error()); $result = mysql_query("SELECT * FROM kalender WHERE dato ='$dato'") or die(mysql_error()); // Hvis det er null reservasjoner i dag, da får vi lov til å registrere reservasjonena i basen if (mysql_affected_rows() == 0) { mysql_query ( "insert into kalender (navn, bil, dato, start_stamp, slutt_stamp, beskrivelse, komment, brukerid ) values ( '$navn', '$bil', '$dato', '$start_stamp', '$slutt_stamp', '$beskrivelse', '$komment', '$brukerid' )" ) or die(mysql_error()); } else { // Lopper gjennom alle rader for denne dagen og legger de i $row while($row = mysql_fetch_array( $result )) { // Er ønsket startidspunkt OG sluttid før neste reservasjon begynner? Det betyr at ønsket tid er ledig og vi kan låne bil if ( $start_stamp < $row['start_stamp'] AND $slutt_stamp < $row['start_stamp']) { mysql_query ( "insert into kalender (navn, bil, dato, start_stamp, slutt_stamp, beskrivelse, komment, brukerid ) values ( '$navn', '$bil', '$dato', '$start_stamp', '$slutt_stamp', '$beskrivelse', '$komment', '$brukerid' )" ) or die(mysql_error()); } // Er ønsket starttidspunkt etter siste reservasjon? Det betyr at ønsket tid er ledig og vi kan låne bil elseif ($start_stamp > $row['slutt_stamp']) { mysql_query ( "insert into kalender (navn, bil, dato, start_stamp, slutt_stamp, beskrivelse, komment, brukerid ) values ( '$navn', '$bil', '$dato', '$start_stamp', '$slutt_stamp', '$beskrivelse', '$komment', '$brukerid' )" ) or die(mysql_error()); } } Men dette vil gjøre at den legger inn data så sant ønsket tid ikke krasjer med den FØRSTE raden.. Er det noen muliget til å vente med å legge inn data før den har loopet igjennom alle dagens reservasjoner og sjekket mot dobbeltbooking? Endret 27. september 2007 av rwd-drifter Lenke til kommentar
ZoRaC Skrevet 27. september 2007 Del Skrevet 27. september 2007 Hva med SELECT bil FROM kalender WHERE start_tamp < $timestamp_start AND end_tamp > $timestamp_end Hvor $timestamp_start er kl 00:00:01 og $timestamp_end er 23:59:59 den dagen. Så looper du igjennom og sjekker om det er den bilen, og hvilke tidspunkter det er. Tror det blir rett? Lenke til kommentar
MirusMentis Skrevet 27. september 2007 Forfatter Del Skrevet 27. september 2007 Hva med SELECT bil FROM kalender WHERE start_tamp < $timestamp_start AND end_tamp > $timestamp_end Hvor $timestamp_start er kl 00:00:01 og $timestamp_end er 23:59:59 den dagen. Så looper du igjennom og sjekker om det er den bilen, og hvilke tidspunkter det er. Tror det blir rett? 9588886[/snapback] Hmm joa, men i det queriet der så får jeg nok ingen, da det er ingen som er mindre enn 00:00:01 og ingen som er større enn 23:59:59 Mulig du misforstod meg, jeg har et query som returnerer alle reservasjoner på en gitt dag.. SELECT bil FROM kalender WHERE dato = $dato Der $dato inneholder den dagen brukeren har klikket på i kalenderen. Problemet mitt er hvordan jeg skal loope gjennom alle radene før jeg vet om jeg kan tilate brukeren å registrere en reservasjon av bilen på det tidrommet han ønsker. Lenke til kommentar
ZoRaC Skrevet 28. september 2007 Del Skrevet 28. september 2007 (endret) Poenget mitt er at dato-feltet er overflødig. Timestamp lager både dato og tid, så du kan bruke det til å hente ut alle reservasjoner for en dag. Du kan vel lage timestamp for din start-tid og sjekke om den er i mellom en reservasjons start og slutt tid (og gjøre det samme med ønsket slutt-tid)? Når du looper igjennom og sjekker kjører du $ledig = true; I løkka: if ("tid kolliderer") { $ledig = false; break; // Ingen grunn til å sjekke resten av reservasjonene hvis du allerede har funnet "kollisjon" } Så sjekker du om ledig er true/false etter løkka. Endret 28. september 2007 av ZoRaC Lenke til kommentar
MirusMentis Skrevet 28. september 2007 Forfatter Del Skrevet 28. september 2007 Poenget mitt er at dato-feltet er overflødig.Timestamp lager både dato og tid, så du kan bruke det til å hente ut alle reservasjoner for en dag. Du kan vel lage timestamp for din start-tid og sjekke om den er i mellom en reservasjons start og slutt tid (og gjøre det samme med ønsket slutt-tid)? Når du looper igjennom og sjekker kjører du $ledig = true; I løkka: if ("tid kolliderer") { $ledig = false; break; // Ingen grunn til å sjekke resten av reservasjonene hvis du allerede har funnet "kollisjon" } Så sjekker du om ledig er true/false etter løkka. 9592157[/snapback] Ahh at jeg ikke tenkte på det.. Jeg kan bruke en variabel til å "holde" om det er ledig eller ikke.. Da trenger jeg kun en ny if i bunn som sjekker om ledig = true før jeg skriver til basen. Men det å sjekke etter ledig tid kan bli litt vanskelig. Se for deg dette: her har jeg forkortet unixtimestamp for å gjøre det lettere. I basen ligger det en reservasjon: startstamp 1500 endstamp 1600 Ola Nordmann ønsker å leie bilen fra start 1200 til 1700 her vil ikke den if løkken treffe.. Slik jeg har kommet frem til må jeg først sjekke om nystart og nystopp er innenfor row['start'] og row['stopp'] (scenario1) deretter sjekke om nystart er før row['start'] OG nystopp er mellom row['start'] og row['stopp'] (scenario2) så sjekke om nystart er mellom row['start'] og row['stopp'] OG nystopp er etter row['stopp'](scenario3) tilslutt sjekke om nystart er før row['start'] OG nystopp er etter row['stopp'] (scenario4) Dette var kun sjekk for èn reservasjon.. Jeg må ta høyde for at det kan ligge 2-3 reservasjoner inne.. Slik at $ledig kan settes til 'false' selv om den gikk igjennom de 2 første reservasjonene.. Lenke til kommentar
Babelfisken Skrevet 3. oktober 2007 Del Skrevet 3. oktober 2007 (endret) Ahh at jeg ikke tenkte på det.. Jeg kan bruke en variabel til å "holde" om det er ledig eller ikke.. Da trenger jeg kun en ny if i bunn som sjekker om ledig = true før jeg skriver til basen. Men det å sjekke etter ledig tid kan bli litt vanskelig. Se for deg dette: her har jeg forkortet unixtimestamp for å gjøre det lettere. I basen ligger det en reservasjon: startstamp 1500 endstamp 1600 Ola Nordmann ønsker å leie bilen fra start 1200 til 1700 her vil ikke den if løkken treffe.. Slik jeg har kommet frem til må jeg først sjekke om nystart og nystopp er innenfor row['start'] og row['stopp'] (scenario1) deretter sjekke om nystart er før row['start'] OG nystopp er mellom row['start'] og row['stopp'] (scenario2) så sjekke om nystart er mellom row['start'] og row['stopp'] OG nystopp er etter row['stopp'](scenario3) tilslutt sjekke om nystart er før row['start'] OG nystopp er etter row['stopp'] (scenario4) Dette var kun sjekk for èn reservasjon.. Jeg må ta høyde for at det kan ligge 2-3 reservasjoner inne.. Slik at $ledig kan settes til 'false' selv om den gikk igjennom de 2 første reservasjonene.. 9594415[/snapback] Du behøver ikke gjøre det vanskeligre for deg selv enn det er. Konflikt oppstår hvis følgende er sannt: $nyStart > $regStart AND $nyStart < $regStop 'Starttid krasjer med en allerede rergistert reservasjon OR $nyStop < $regStop AND $nyStop > $regStart 'Stoptid krasjer med en allerede rergistert reservasjon OR $nyStart > regStart AND $nyStop < $regStop 'Start og stopp spenner forbi start og stop på en allerede registert reservasjon. Dette ligger altså inni loopen ved treff setter @ledig = false. Finnes sikkert andre måter å gjøre dette på men det burde funke. Det som kan være et problem er reservasjoner over flere døgn. Du må nok utvide søkegrunnlaget, altså SQL spørringen dersom dette er mulig. Det slo meg at logikken over faktsik burde ligge i selve SQL spørringen. Returnerer spørringen en eller flere rader er bilen booket. Ingen looper i PHP og minimal trafikk. "Select * from kalender where Car_ID = '$Valgt bil' AND ( '$nyStart' > StartTime AND '$nyStart' < EndTime OR '$nyStop' < EndTime AND '$nyStop' > StartTime OR '$nyStar't > StartTime AND '$nyStop' < EndTime )" Da blir også problemstillingen med bli booket over flere dager borte. Endret 3. oktober 2007 av Babelfisken Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå