Autor Zpráva
Donny
Profil *
Dobrý deň,

Vytvoril som si taký relatívne jednoduchý dochádzkový systém pre moju firmu, ktorá sprostredkuje zamestnanie vo výrobných závodoch ale ostal som dosť zaskočený že časť ktorú som považoval za zložitejšiu ide bez problémov a časť ktorá mala byť lahšia robí problémy. Funguje to asi tak že, Ferko ráno príde do práce, kartou prebehne cez snímač ten zapíše do databáze že userko číslo xyz prišiel do práce 8.1.2013 o 14:00. Toto funguje krásne.

Na druhej strane systému v kancelárií sedí operátorka ktorá príma hovory a pracuje zo systémom. Ak príde niekto do práce pekne to tam v reporte vidí.. toto funguje až nadočakávanie dobre.

Teraz, existuje ale možnosť že Ferko zavolá operátorke že od 20.01.2013 do 27.01.2013 chce mať dovolenku. Operátorka to cez jednoduchý formulár zapíše do systému (do tabulky UserAbsences). Pretože som si chcel prácu zjednodušiť a zároveň som si myslel že bude efektívnejšia editácia ak sa operátorka pomýli, resp. pri schvaľovaní absencie tak som si zvolil nasledovnú štruktúru tabuľky:

|Id|userId|From|To|AbsenceType|Arrival|Leave|CreatedDate|CreatedBy|Status|
|1|1|2013-01-01|2013-01-15|14:00|16:00|1|2012-12-24|1|1|
|1|54|2013-01-15|2013-01-17|08:00|16:00|2|2012-12-24|1|1|
|1|64|2013-01-04|2013-01-15|07:00|16:00|4|2012-12-24|1|1|

Pričom jednotlivé stĺpce znamenajú toto:
Id - je cislo zaznamu
userId - je cislo zamestnanca
absenceFrom - je odkedy nebude v praci
absenceTo - je dokedy nebude v praci
arrival - príchod
leave - odchod
absenceType - typ absencie, id s pomocnej tabulky (napr 1 - dovolenka, 2 - nahradne volno..)
absenceAproved - ci je absencia schválena, napr. na základe dokladu od lekára a pod..
note - poznámka
createdDate - kedy do bolo vytvorene
createdBy - kto to vytvoril
status - zo systemu sa nic bez kontroly opravneho uzivatela nemaze, vsetko sa iba skryva, 1 - zaznam je zobrazeny, 0 - zaznam je skryty a caka na potvrdenie ze to je možné zmazať..

Chcel by som spraviť aby sa dalo cez formulár dohľadať napr. koľko bol Ferko v rámci nejakého termínu na dovolenke. Myslel som že to bude pôjde
hľadko cez Between, vymyslel som takýto dotaz z ktorého som pre zjednodušenie dotazu vypustil zamestnanca aj typ absencie. Takisto čas momentálne vôbec nezaujíma..
<?php
  $dotaz = $sql->query(Select * from UserAbsences where (absenceFrom between  '$firstDay' and '$lastDay') or (absenceTo between  '$firstDay' and '$lastDay'));          
  while($obj = $sql->objects('', $dotaz))          
  {
       print_r($obj);
  }
?>

Pôvodne sa zdalo že by to mohlo byť ono, ale logicky to protestuje napr. v prídpade ak má userko absenciu napr. od 1.12.2012 do 1.2.2013 lebo mal zlomenú nohu. Viem prečo to nefunguje ale nenapáda ako ho vyriešiť takýmto spôsobom..

Jediným riešením, ktoré ma napadlo je ukladanie každého dňa absencie samostatne ale s praktického hľadiska sa my to nezdá byť ok. Napr. ak by nebol v práci 2 mesiace vygeneruje to cca 60 riadkov v tabuľke a ak sa náhodou v poznámke operátorka pomýlila, resp. donesie doklad od lekára tak všetkých tých 60 záznamov budem musieť editovať (áno dá sa to rôzne zjednodušiť pre užívateľa ale tých 60 dotazov tam zostane vždy)..

Nemáte niekto skúsenší nejaký nápad?

Ďakujem.


len poznámka, pri spätnej kontrole môjho príspevku som si všimol že tu (iba tu, v systéme to je ok) v štruktúre tabuľky mám dve chyby v názvoch stĺpcov. Konkrétne v položkách From a To, má to byť absenceFrom a absenceTo ako je to v popiskoch..
Kajman
Profil
Vypsání absencí, které spadají do zvoleného termínu
Select * from UserAbsences where absenceFrom<='$lastDay' and absenceTo>='$firstDay'

Pro výpočet přesného počtu dní by se hodila pomocná tabulka s kalendářem, která by se také omezila na termín a zjoinovala díky between s uvedeným dotazem. Pak by se použil count(distinct den_z_kalendare).
Donny
Profil *
Ďakujem za radu. Tak toto ma dosť zaskočilo čakal som vnorené dotazy ono to má také jednoduché riešenie..

Výpočet počtu dní by som asi skôr spravil funkciou v PHP, ktorá by my mala vrátiť počet dní medzi dátumami, ktoré som vytiahol cez cyklus vďaka vašemu dotazu. Či myslite že to nie je dobré riešenie?

<?php 
  function dateDiff($start, $end) 
  {
      $day = 86400; 
      $format = 'Y-m-d'; 
      $sTime = strtotime($start);
      $eTime = strtotime($end); 
      $numDays = round(($eTime - $sTime) / $day) + 1;
      return $$numDays; 
  }   
?>  
Kajman
Profil
Nemáte za returnem moc dolarů?

Jen nezapomeňte zohlednit stavy, kdy jeden zaměstnanec má více absencí v jeden den a kdy je absence i mimo počítaný termín. Ono je celkem asi jedno, kde to spočítáte (předpokládám, že nemáte tisíce zaměstnanců - to byste si to asi neprogramoval sám ;)
Donny
Profil *
Áno moc dolárov tam je, bolo to dosť splácané narýchlo a Vaše poznámky určite zakomponujem ;). Okrem toho by tam asi nemuselo byť toľko pomocných premenných - strtotime môže byť aj vo vzorci. To len poznámka ak by to náhodou niekto chcel použiť..

Tisíce zamestnancov nemám, to je síce pravda ale programujem si to sám skôr pretože ma to baví (teda hlavne tá časť zo snímaním karty ma bavila).. Väčšina firiem v tejto oblasti funguje papierovou formou, resp. veľké firmy zase cez SAP.
tiso
Profil
Donny: čo pracovné/nepracovné dni?
donny
Profil
Tiso, zaujímavá otázka, ale na soboty a nedele sa vo výrobných podnikoch spravidla nehráme. Jediná vec, ktorú som musel riešiť sú sviatky, odstávky alebo iné mimoriadne situácie (riešil som to už dávnejšie, pri dochádzke). Tie som sa rozhodol dávať do samostatnej pomocnej tabuľke enforcedAbsences, do ktorej to operátorka zadá manuálne cez formulár. Táto tabuľka, má ale len jedno dátumové políčko :), ak je odstávka, alebo sviatok od do tak tam nageneruje x riadkov.

Takže okrem dotazu ktorý poradil Kajman, robím ešte dotaz jeden ktorý testuje či v danom termíne od do neboli ešte nejaké enforcedAbsences a tie potom od pôvodného výsledku odrátam.

Ak by som musel zohľadňovať aj soboty a nedele, tak by som tú funkciu datediff upravil tak aby okrem poctu dni medzi dvomi premennymi otestovala a prípade odratala vikendy.. nieco taketo..

 <?php
 Class Reports
{
//zisti pocet dni medzi datum - start a datum 
function dateDiff($start, $end) 
{
  $day = 86400; 
  $format = 'Y-m-d'; 
  $sTime = strtotime($start);
  $eTime = strtotime($end); 
  $numDays = round(($eTime - $sTime) / $day) + 1;
  $days = array();
  $weekendDays = 0;     
  for ($d = 0; $d < $numDays; $d++) 
  {
    if($this->isWeekend(date($format, ($sTime + ($d * $day)))))
    {
       $weekendDays++;
    }
  }
  $result = $numDays - $weekendDays;
  return $result;
}
//funckia zisti ci zadany datum je sobota alebo nedela
function isWeekend($date) 
{
  $weekDay = date('w', strtotime($date));
  if ($weekDay == 0 || $weekDay == 6)
  {
    return false;
  } 
  else
  {
    return true;
  } 
}    
?>

Neni to testované a asi tam sú aj dake chyby (ved je už hlboka) noc ale princíp je asi zrozumitenlny..
abc
Profil
Dovolím si oponovat té tvé funkci "isweekend", která by měla vracet boolean přesně obráceně!
Tj. takto:
function isWeekend($date) 
{
  $weekDay = date('w', strtotime($date));
  if ($weekDay == 0 || $weekDay == 6)
  {
    return true;
  } 
  else
  {
    return false;
  } 
}    
donny
Profil
Jasné máte / máš pravdu ale vzhľadom na to že som to robil narýchlo a bolo 23:40 tak si myslím že tú jednu chybičku my účastníci diskusie odpustia.. aj tak to bolo už len také OT pre zaujímavosť ;)

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: