Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    Ciclo PHP molto complesso

    Salve a tutti, sono abbastanza nuovo al PHP e sto affrontando alcune problematiche molto toste.
    Vi spiego il mio problema che ormai mi assilla da due giorni e ancora non ho trovato una soluzione.
    Il risultato è un "cartellino online" delle ore lavorate al netto dell'inattività dell'utente. Vi spiego il funzionamento: la mattina l'utente fa "Avvio" su di una pagina e viene registrato un datalog, nel caso il mouse resti fermi per 10 minuti parte uno script che registra i minuti di inattività, al movimento del mouse vengono registrate i minuti di inattività in tabella, al termine del lavoro l'utente fa "Stop" e viene anche qui registrato un datalog. Il risultato come ho detto è cercare le ore lavorate al netto dell'inattività, e questo sono riuscito a farlo seppur con qualche difficoltà, con una sottrazione tra stop e avvio - il tempo di inattività. Il problema sorge quando gli utenti non fanno ciò che gli si era chiesto di fare, ossia premono "Start" o "Stop" più volte o "a caso". Infatti succede che se viene premuto START - STOP, poi di nuovo START - STOP, io a video ho due colonne che mi riportano la stessa data e il risultato (ad esempio 01/10/2015 1 ora - 1/10/2015 1 ora e mezza), ciò che io vorrei è la somma di queste ore lavorate e un controllo sulle azioni che fa l'utente perchè ci sono problemi anche nel caso in cui l'utente faccia START - START - STOP, il programma prende in considerazione solamente il secondo start. Inoltre vorrei che il punto di partenza sia sempre e solo lo start (capita a volta che parte l'inattività per colpa delle donne delle pulizie che muovono il muose e poi lo script parte, ma questi sono casi proprio eccezionali e poi ci penso). Purtroppo educare gli utenti è complicato vorrei risolvere il problema magari con un'indicazione da parte Vostra. Vi posto il codice sotto. A monte di tutto c'è una query che mi tira fuori i vari dati idoperatore, datalog, etc, poi me li vado a recuperare sotto.
    La logica che ho utilizzato: il programma entra e mette blank a tutti i campi fino a che non trova stesso operatore e stessa data e fa il check sulle azioni (da me nominate 1 - Start, 3 - Overtime che andrà ad autoincrementarsi , 4 - Stop). Sul 4 lui fa i calcoli necessari per tirarmi fuori il tempo e funziona benissimo. Ora stavo provando ad utilizzare 2 altre variabili azioneold e azionenew per dirgli se azioneold è diversa da azionenew fai che vai oltre, ma giuro che mi sono perso.
    Idee?



    $RsSql=$oConn->Query($strSql);
    if ($oConn->RecordCount>0)
    $nRec = $oConn->RecordCount;
    else
    $nRec = 0;

    $operatore1 = "";
    $ora1 = "";
    $data1 = "";

    $operatore0 = "";
    $ora0 = "";
    $data0 = "";
    //$nextstep = "1";
    //$primostep = "";
    $azioneold = "";

    /* $str1 = "prova";
    $str2 = "si";
    $pos = strpos($str1,$str2);
    echo $pos;
    */
    while(!$oConn->EOF) {

    $azionenew = $RsSql['azione'];
    //echo $azione ;
    $datafunk = "";
    $data = $RsSql['Data'];
    $cellaora = "";
    $operatore1 = $RsSql['nome'];
    $descrizione = $RsSql['Descrizione'];
    $pos = strpos($azione,$nextstep);
    //echo $pos."-".$nextstep."<br/>";



    SWITCH ($azionenew) {

    case 1:
    //if ( isset($pos) && !empty($pos) ) {
    //$nextstep = 3 || 4;
    if ($azionenew != $azioneold) {

    $datafunk1 = $RsSql['datafunk'];
    //$data1 = substr($RsSql['Data'], 0 , 10);
    $data1 = $RsSql['Data'];
    $overtime = "";
    }

    echo $azionenew;
    //}
    break;

    case 3:
    //if ($pos >0) {
    // $nextstep = 4;
    $overtime += $RsSql['Overtime'];
    echo $azionenew;
    //}

    break;

    case 4:
    //if ($pos >0) {
    //$primostep = 1;
    $descrizione = "Ore Lavorate";
    $datafunk = $RsSql['datafunk'];
    echo $azionenew;

    break;
    //}
    }

    if (($operatore1 == $operatore0) && ($data1 == $data0) && ($azionenew == 4) ) {
    //$stop = $datafunk;

    $lavorato = abs(strtotime($datafunk) - strtotime($datafunk1));
    $minutes = floor($lavorato / 60);
    $cellaora = $minutes - $overtime;
    $cellaora = substr(($cellaora / 60),0,4);
    $StrDati.=" <tr>";
    $StrDati.=" <td>".$RsSql['nome']."</td>
    <td>".$data0."</td>

    <td>".$descrizione."</td>
    <td>".$cellaora."</td>
    </tr>";
    }
    Ultima modifica di chinoknot; 21-10-2015 a 18:18

  2. #2
    Non so perchè fa vedere il codice così male.

  3. #3
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,505
    Perché lo devi mettere tra i tag [php] e [ /php] (quest'ultimo senza lo spazio tra [ e /)

  4. #4
    Utente bannato
    Registrato dal
    Jul 2013
    Messaggi
    290
    a me sembra un gran kasino.
    qualche domanda
    1) supponendo che i lavori si facciano in un giorno, cioè non durino più delle 24:00, io inizierei a prendere da
    SQL il primo START e l'ultimo STOP (mettendoci dentro un campo timestamp)
    così risolvi il problema delle cliccate multiple
    2) se l'ultimo STOP non esiste, allora prendi l'ultima operazione registrata e considerala come STOP
    (se si dimenticano di premerlo)
    3) memorizza una riga che so SVEGLIO quando si muove il mouse, e una DORMO quando non si muove.
    Poi fai una SUM della differenza di DORMO-SVEGLIO (servirà magari una gestione di START e STOP)

  5. #5
    mah, un pò un casino... cmq direi:

    click su START -> log inizio attività ( da ora non esisterà piu il pulsante start ma solo il pulsante stop e non si potrà piu in nessun modo umano e non avere un altro start senza prima uno stop)

    click su STOP -> log fine attività ( da ora non esisterà piu il pulsante stop ma solo il pulsante start e non si potrà piu in nessun modo umano e non avere un altro stop senza prima uno start)

    da cui il calcolo è banale. pure se l'utente fà seimila volte start/stop, avrai sempre start e stop a coppie ben distinte

    per gestire l'inattività invece, diciamo che "dipende" da quello che fai. Un'idea potrebbe essere che dopo X minuti di mouse fermo, il sistema inserisce in automatico un log "STOP" e, appena il mouse torna a muoversi, rimette un log "START" ( al limite entrambi fleggati in maniera particolare per riconoscere il caso di inattività da uno start/stop volontario dell'utente). Detto questo a fine lavoro dovresti avere una serie di log del tipo:

    codice:
    START - 8:00
    
    STOP(i) - 9:00
    START(i) - 9:15
    
    STOP - 13:00
    
    START - 14:00
    
    STOP(i) - 15:30
    START(i) - 15:50
    
    STOP - 18:00
    simulando due periodi di inattività (quelli con la (i) ). a quel punto per il calcolo delle ore lavorate, istanzi un contatore di minuti a 0 e aggiungi a questo contatore i minuti che interrcorrono tra uno start e uno stop. a meta codice:

    Codice PHP:

    $minutes 
    0;

    $records get_from_db("select * from datalog where id_utente = " id_utente " and giorno(data_log) = giorno_che_voglio_conteggiare order by data_log asc")

    $start null;

    foreach(
    $records as $record)
    {

         
    se record['tipo_di_log'] == START do: $start $record['data_log'];

         
    se record['tipo_di_log'] == STOP do: 
                 
    $minutes += get_differenza_in_minuti($record['data_log'], $start);
                 
    $start null;
         
    done;

    }

    print 
    "ore lavorate: " . ($minutes/60); 
    i problemi li hai se:

    a) non hai lo stop alla fine della giornata di lavoro (l'utente magari ha chiuso il programma senza cliccare stop e non si è salvato il log). a quel punto un'idea di massima è dire: "caro utente, visto che non hai chiuso il programma spingendo stop, io ti conteggio le ore a partire dal primo start della giornata fino ad uno stop ipotetico avvenuto alle ore XX. Se poi hai lavorato di più, cavoli tuoi"

    b) se il programma salva male i log

    c) se il lavoro cade a cavallo di due giorni (il mio pseudo script non comprende tale eventualità)

    un'idea anche per l'utente che usa il programma: quando scatta lo stop per inattività, mettere nella pagina un overlay con l'avviso "il sistema ha rilevato l'inattività dell'utente, il conteggio dei minuti a fine retributivo ripartirà al riprisitino dell'attività dell'utente" o qualcosa del genere.
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  6. #6
    Grazie della risposta, ora provo a metterla in "funzione". Per quanto riguarda il pulsante, noi ci abbiamo provato a farlo non cliccabile, ma ti assicurano che fanno di tutto per metterci in difficoltà, premono F5 fanno il refresh della pagina e il pulsante torna cliccabile.
    Ho anche una serie di 3 start e niente stop.
    Per quanto riguarda lo script di inattività, non posso mettere un avviso.

  7. #7
    Quote Originariamente inviata da chinoknot Visualizza il messaggio
    premono F5 fanno il refresh della pagina e il pulsante torna cliccabile.
    Scusa eh, ma fare un pulsante non cliccabile è una cavolata: l'utente è loggato, SAI quindi che ha cliccato start, e allora non lo rendi cliccabile mettendoci, che so, una immagine quando stampi da php il bottone e facendo un check lato server se l'utente riesce a scavalcare la cosa. Se ti affidi solo a controlli lato client (browser, alias javascript) è normale che l'utente prima o poi un modo per fregarti lo trova. I controlli si fanno lato client e lato server, perchè non ti puoi fidare dei dati che un client ti manda.
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  8. #8
    Dunque sono riuscito ad andare avanti in questo modo. Funziona tutto benissimo ora. Ho solo il problema dell'ordine delle funzioni, l'azione 3 (minuti di inattività) deve essere sempre compresa tra lo start (1) e lo stop (4). Come si riesce a fare questo tipo di controllo? Di seguito il codice, che nonostante tutto, sporco, brutto e incasinato, funziona!

    $RsSql=$oConn->Query($strSql);
    if ($oConn->RecordCount>0)
    $nRec = $oConn->RecordCount;
    else
    $nRec = 0;

    $operatore1 = "";
    $ora1 = "";
    $data1 = "";

    $operatore0 = "";
    $ora0 = "";
    $data0 = "";








    //echo $RsSql['datafunk'];
    while(!$oConn->EOF) {

    //echo $RsSql['idoperatore'];
    //echo $RsSql['datafunk'];
    //VERIFICO SE CI SONO OVERTIME
    if (( $RsSql['idgruppolavorazione'] == 66) && isset($RsSql['azione'] == 1)){
    $datafunk1 = $RsSql['datafunk'];
    $overtime = "";

    $dataOT = date('Y-m-d', strtotime($RsSql['datafunk']));
    //$dataOT = substr($RsSql['datafunk'],0,11);
    $dataOT = str_replace("-","",$dataOT);

    $strSqlOT = " SELECT isnull (sum(overtime),0) as overtime
    from lst_activitiLog l
    inner join lst_activitiMachine m on l.IpPc=m.Ip
    where m.Operatore = '".$RsSql['idoperatore']."' and overtime is not null
    and convert(varchar,l.datalog, 112) = '".$dataOT."' ";
    $RsSqlOT=$oConnOT->Query($strSqlOT);
    if ($oConnOT->RecordCount>0){

    while($oConnOT->EOF) {
    $overtime = $RsSqlOT['overtime'];
    $RsSqlOT=$oConnOT->MoveNext();
    }
    }

    //echo $RsSqlOT['overtime'] ;

    }


    if (( $RsSql['idgruppolavorazione'] == 79) && ($RsSql['azione'] == 1)){
    $datafunk1 = $RsSql['datafunk'];
    $overtime = "";

    $dataOT = date('Y-m-d', strtotime($RsSql['datafunk']));
    //$dataOT = substr($RsSql['datafunk'],0,11);
    $dataOT = str_replace("-","",$dataOT);

    $strSqlOT = " SELECT isnull (sum(overtime),0) as overtime
    from lst_activitiLog l
    inner join lst_activitiMachine m on l.IpPc=m.Ip
    where m.Operatore = '".$RsSql['idoperatore']."' and overtime is not null
    and convert(varchar,l.datalog, 112) = '".$dataOT."' ";
    $RsSqlOT=$oConnOT->Query($strSqlOT);
    if ($oConnOT->RecordCount>0){

    while($oConnOT->EOF) {
    $overtime = $RsSqlOT['overtime'];
    $RsSqlOT=$oConnOT->MoveNext();
    }
    }

    //echo $RsSqlOT['overtime'] ;

    }





    $azione = $RsSql['azione'];

    $datafunk = "";
    $data = $RsSql['Data'];
    $cellaora = "";
    $operatore1 = $RsSql['nome'];
    $descrizione = $RsSql['Descrizione'];



    /*if($azione==1)
    {
    $datafunk1 = $RsSql['datafunk'];
    $overtime = "";*/

    //}
    if ($azione == 4){
    $descrizione = "Ore Lavorate";
    $datafunk = $RsSql['datafunk'];

    }
    /*elseif($azione==3)
    {
    $overtime += $RsSql['overtime'];

    //$RsSql['Overtime']
    }*/




    if (($operatore1 == $operatore0) && ($data1 == $data0) && ($azione == 4) ) {
    //$stop = $datafunk;

    $lavorato = abs(strtotime($datafunk) - strtotime($datafunk1));
    $minutes = floor($lavorato / 60);
    if ( $RsSql['idgruppolavorazione'] == 66) {
    $cellaora = $minutes - $RsSqlOT['overtime'];
    }
    else
    {
    $cellaora = $minutes;
    }

    $cellaora = substr(($cellaora / 60),0,4);

    $StrDati.=" <tr>";
    $StrDati.=" <td>".$RsSql['nome']."</td>
    <td>".$data."</td>

    <td>".$descrizione."</td>
    <td>".$cellaora."</td>
    </tr>";


    }


    $i++;





    $operatore0 = $RsSql['nome'];

    //$data0 = substr($RsSql['Data'], 0 , 10);

    //echo $cellaora;


    $tot += $cellaora;



    $RsSql=$oConn->MoveNext();


    }

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.