Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 70
WF_DisplayTable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 6
552.00
0.00% covered (danger)
0.00%
0 / 70
 get_css
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 tableDated
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 18
 cuadritoDated
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 19
 prevLabeled
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 6
 tableNums
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 16
 cuadritoNums
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
<?php
namespace ia\Work\Workflow;
/*
gantt graph
    https://frappe.io/gantt
project managment
    https://github.com/opf/openproject
    https://github.com/neuronetio/gantt-elastic
*/
use DateTime;
use Exception;
use function htmlentities;
use function implode;
use function str_repeat;
class WF_DisplayTable {
    protected $format = 'j/M\<\b\r\>D';
    public static function get_css() {
        return <<< CSSOUT
            TABLE.iawfSched {border-collapse:collapse;border:1px silver solid;empty-cells: show;}
            TABLE.iawfSched CAPTION {font-weight:bold;font-size:1.4em;vertical-align:middle;text-align:center;border:1px silver solid;}
            TABLE.iawfSched TH {text-align:center;vertical-align:top;border:1px silver solid;}
            TABLE.iawfSched TD {text-align:left;vertical-align:top;border:1px silver solid}
            TABLE.cuadrito {border-collapse:collapse;border:1px blue solid;empty-cells: show;width:100%}
            TABLE.cuadrito TH {vertical-align:top;border:1px blue solid}
            TABLE.cuadrito TD {vertical-align:top;border:1px blue solid}
            TABLE.cuadrito .cen {text-align: center;}
            TABLE.cuadrito .der {text-align: right;}
            TABLE.cuadrito .detalle {color:gray}
            TABLE.cuadrito .est {color:green}
            TABLE.cuadrito .duration {}
            TABLE.cuadrito .actname {}
            TABLE.cuadrito .lst {color:green}
            TABLE.cuadrito .eet {}
            TABLE.cuadrito .slack {color:blue}
            TABLE.cuadrito .let {color:red}
CSSOUT;
    }
    /**
     * @param $datedWorkflow
     * @return string
     * @throws Exception
     */
    public function tableDated($datedWorkflow) {
        $max = 0;
        $activityList = $datedWorkflow->get_activityList();
        foreach($activityList as $activity_id => $act)
            if($max < $act['let'])
                $max = $act['let'];
        $rows = [];
        foreach($activityList as $activity_id => $act) {
            $preCol = str_repeat('<td>&nbsp;', $act['est']);
            $postCol = str_repeat('<td title="'.($max - $act['let']+1).'">&nbsp;', $max - $act['let']+1);
            $colspan = $act['duration'];
            $rows[] = $preCol."<td colspan='$colspan'>".$this->cuadritoDated($act, $activityList).$postCol;
        }
        $th = [];
        $days = $datedWorkflow->get_days();
        foreach($days as $date => $hours) {
            $th[] = (new DateTime($date))->format($this->format);
        }
        return '<table class="iawfSched"><caption>Process</caption><thead><tr><th>'.implode('<th>', $th).  '</thead><tbody>'
           .'<tr>'. implode('<tr>', $rows)
           .'</tbody></table>';
    }
    private function cuadritoDated($act, $activityList) {
        $label = htmlentities($act['label']);
        $labelTitle = empty($act['prev']) ? '' : 'Requiere: '. htmlentities(implode(',', $this->prevLabeled($act, $activityList) ),ENT_QUOTES );
        $est = $act['plan']['est']->format($this->format);
        $lst = $act['plan']['lst']->format($this->format);
        $iniciar = "<i>Inicia:</i> $est" . ($est === $lst ? ''  : " <i>a mas $lst</i>");
        $eet = $act['plan']['eet']->format($this->format);
        $let = $act['plan']['let']->format($this->format);
        $terminar = "<i>Terminar:</i> $eet" . ($eet === $let ? ''  : " <i>a mas $let</i>");
        $details = "<i>Plan:</i> $act[duration] días " . ($eet === $let ? ''  : "$act[slack] <i>de holguara</i>");
        if(empty($act['prev'])) {
            $requiere = '';
        } else {
            $prevLabels = [];
            foreach($act['prev'] as $prev) {
                $prevLabels[] = htmlentities('"'.$activityList[$prev]['label'].'"');
            }
            $requiere = "<br /><i>Requiere:</i> ". implode(', ', $prevLabels);
        }
        // $start = $this->dateRange($act['plan']['est'],$act['plan']['lst']);
        // $end = $this->dateRange($act['plan']['eet'],$act['plan']['let']);
        return <<< TABLITA
        <table class='cuadrito'>
            <tr><td class='cen actname' title='$labelTitle'>$label
            <tr><td class='detalle'>$iniciar
            <tr><td class='detalle'>$terminar
            <tr><td class='detalle'>$details.$requiere
        </table>
TABLITA;
    }
    /*
    private function dateRange($earliest, $latest) {
        $earliestFormatted = $earliest->format($this->format);
        $latestFormatted = $latest->format($this->format);
        if($earliestFormatted === $latestFormatted) {
            return $earliestFormatted;
        }
        return $earliestFormatted." - ".$latestFormatted;
    }
    */
    private function prevLabeled($act, $activityList) {
        if(empty($act['prev'])) {
            return '';
        }
        $prev = [];
        foreach($act['prev'] as $activity_id) {
            $prev[] = $activityList[$activity_id]['label'];
        }
        return $prev;
    }
//____________________________________________________________________
    public function tableNums($activityList) {
        $max = 0;
        foreach($activityList as $activity_id => $act)
            if($max < $act['let'])
                $max = $act['let'];
        $rows = [];
        foreach($activityList as $activity_id => $act) {
            $preCol = str_repeat("<td>&nbsp;", $act['est']);
            $postCol = str_repeat("<td title='".($max - $act['let']+1)."'>&nbsp;", $max - $act['let']+1);
            $colspan = $act['duration'];
            $rows[] = $preCol."<td colspan='$colspan'>".$this->cuadritoNums($act, $activityList).$postCol;
        }
        $th = [];
        for($i=0;$i<=$max;$i++)
            $th[] = "$i";
        // https://stackoverflow.com/questions/37071535/position-sticky-firefox-on-a-table-element ver ejemplo 5
        return "<table class='iawfSched'><caption>Process</caption><thead><tr><th  style='position:sticky;top:0;'>"
            . implode("<th style='position:sticky;top:0;'>", $th) . "</thead>
            <tbody style='overflow:scroll;max-height:50px!important;'>"
           .'<tr>'. implode('<tr>', $rows)
           .'</tbody></table>';
    }
    private function cuadritoNums($act, $activityList) {
        $label = htmlentities($act['label']);
        $labelTitle = empty($act['prev']) ? '' : 'Requiere: '
            . htmlentities(implode(',', $this->prevLabeled($act, $activityList) ),ENT_QUOTES );
        return <<< TABLITA
        <table class='cuadrito'>
            <tr>
                <td title='Primera fecha para iniciar' class='est detalle'>$act[est]
                <td title='Tiempo toma la actividad' class='cen duration detalle'>$act[duration]
                <td title='Última fecha para iniciar' class='der lst detalle'>$act[lst]
            <tr>
                <td colspan='3' class='cen actname' title='$labelTitle'>$label
            <tr>
                <td title='Termina el' class='est detalle'>$act[eet]
                <td title='Holgura' class='cen slack detalle'>$act[slack]
                <td title='Última fecha en que puede terminar' class='der let detalle'>$act[let]
        </table>
TABLITA;
    }
}