« Back to History
loom_patia_machine.php
|
20260723_000646.php
Initial Domain Snapshot
Copy Code
<?php /* ============================================================================= File: /erp/loom_patia_machine.php Purpose: Machine-wise Patia (Date × Karigar columns) — Taka No REMOVED Filters: Khata, Karigar (optional), Machine, Month, Half Scope: Page-local only. No global/base changes. Company-scoped. ============================================================================= */ header('X-Frame-Options: SAMEORIGIN'); error_reporting(E_ALL); ini_set('display_errors', 1); /* ---------- [0] Auth ---------- */ require __DIR__ . '/modules/auth/auth.php'; require_login(); $u = auth_user(); $company_id = (int)$u['company_id']; $user_id = (int)$u['id']; $role = strtolower($u['role'] ?? ''); $pdo = $GLOBALS['pdo'] ?? null; if (!$pdo) { require __DIR__ . '/core/db.php'; } /* ---------- [0A] Helpers ---------- */ function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function gv($k,$d=null){ return isset($_GET[$k]) ? (is_array($_GET[$k])?$_GET[$k]:trim((string)$_GET[$k])) : $d; } function n($v,$dec=0){ return number_format((float)$v, $dec, '.', ''); } function _table_exists(PDO $pdo, $name){ try { $pdo->query("SELECT 1 FROM `$name` LIMIT 1"); return true; } catch(Exception $e){ return false; } } function half_month_range(int $y,int $m,int $half){ $start = sprintf('%04d-%02d-%02d', $y, $m, $half===1?1:16); $end = (new DateTime("$y-$m-01"))->modify($half===1?'+14 days':'last day of this month')->format('Y-m-d'); return [$start,$end]; } function date_list($start,$end){ $out=[]; $d=new DateTime($start); $e=new DateTime($end); for(; $d <= $e; $d->modify('+1 day')) $out[]=$d->format('Y-m-d'); return $out; } function _is_maria(PDO $pdo): bool { try{ $v=(string)$pdo->query("SELECT @@version")->fetchColumn(); }catch(Throwable $e){ return false; } return stripos($v,'mariadb')!==false; } function _norm_date($s){ // '04-08-2025' / '04/08/2025' / '2025-08-04' → '2025-08-04' $s=trim((string)$s); if($s==='') return null; if (preg_match('/^\d{4}-\d{2}-\d{2}$/',$s)) return $s; if (preg_match('/^(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})$/',$s,$m)) return sprintf('%04d-%02d-%02d',$m[3],$m[2],$m[1]); $ts=strtotime($s); return $ts?date('Y-m-d',$ts):null; } /* ---------- [1] Filters ---------- */ $today = new DateTime('now'); $month_str = gv('month', $today->format('Y-m')); $half = (int)gv('half', 1); [$Y,$M] = array_map('intval', explode('-', $month_str)); [$date_from,$date_to] = half_month_range($Y,$M,$half); $khata_id = (int)gv('khata_id', 0); $karigar_id = (int)gv('karigar_id', 0); // OPTIONAL $machine_id = (int)gv('machine_id', 0); $do_csv = (int)gv('csv',0) === 1; /* ---------- [2] Role-based access ---------- */ $allow = in_array($role, ['owner','admin'], true); $self_karigar_id = 0; if (!$allow && $role==='karigar') { if (_table_exists($pdo,'loom_karigar_login')) { $q=$pdo->prepare("SELECT karigar_id FROM loom_karigar_login WHERE company_id=? AND user_id=? LIMIT 1"); $q->execute([$company_id,$user_id]); $self_karigar_id = (int)$q->fetchColumn(); } if ($self_karigar_id>0) { $allow=true; $karigar_id=$self_karigar_id; } // Karigar role = self-only } if(!$allow){ http_response_code(403); echo "<h1>403</h1><p>Access denied. Only Owner/Admin or mapped Karigar can view.</p>"; exit; } /* ---------- [3] Khatas (with ranges) ---------- */ $KHATAS=[]; $KHATA_MAP=[]; if (_table_exists($pdo,'khatas')){ $st=$pdo->prepare("SELECT id, code, name, machine_from, machine_to FROM khatas WHERE company_id=? AND (is_active=1 OR is_active IS NULL) ORDER BY id"); $st->execute([$company_id]); foreach($st->fetchAll(PDO::FETCH_ASSOC) as $r){ $KHATAS[]=$r; $KHATA_MAP[(int)$r['id']] = [ 'code'=>$r['code'],'name'=>$r['name'], 'from'=>(int)$r['machine_from'],'to'=>(int)$r['machine_to'] ]; } } /* ---------- [4] Karigar dropdown source + name map ---------- */ $KARIGAR_LIST = []; // [{id,name}] $KNAME_BY_ID = []; // id => name if (_table_exists($pdo,'loom_karigar_master')){ $sql = "SELECT id, karigar_name, khata_id FROM loom_karigar_master WHERE company_id=?"; $args= [$company_id]; if ($khata_id>0){ $sql .= " AND khata_id=?"; $args[]=$khata_id; } $sql .= " ORDER BY karigar_name"; $q=$pdo->prepare($sql); $q->execute($args); foreach($q->fetchAll(PDO::FETCH_ASSOC) as $r){ $nm = trim((string)$r['karigar_name']); if($nm==='') $nm='Karigar#'.$r['id']; $id = (int)$r['id']; $KARIGAR_LIST[]=['id'=>$id,'name'=>$nm]; $KNAME_BY_ID[$id]=$nm; } } /* ===================== [5] FETCH LINES BY LINE-DATE ====================== */ /* Build: - DAY grid: $DAY[date][karigar_id] = sum(meters) - MACHINE_SET for header - KARIGAR_TOTALS for chips/footer ------------------------------------------------------------------------ */ $DATES = date_list($date_from,$date_to); $DAY = []; // per-date, per-karigar sum $MACHINE_SET = []; // unique machines post-filters $KARIGAR_TOTALS = []; // per-karigar total (respecting filters) $ALL_KARIGARS_SET = []; // for deciding columns when karigar not selected $_skipped_bad_date = 0; $_skipped_out_range = 0; $from_ts = strtotime($date_from.' 00:00:00'); $to_ts = strtotime($date_to.' 23:59:59'); $accum = function($d,$kid,$m,$mc) use (&$DAY,&$KARIGAR_TOTALS,&$ALL_KARIGARS_SET,&$KNAME_BY_ID,&$MACHINE_SET){ if(!isset($DAY[$d])) $DAY[$d]=[]; $DAY[$d][$kid] = ($DAY[$d][$kid] ?? 0) + $m; $KARIGAR_TOTALS[$kid] = ($KARIGAR_TOTALS[$kid] ?? 0) + $m; $ALL_KARIGARS_SET[$kid] = true; if(!isset($KNAME_BY_ID[$kid])) $KNAME_BY_ID[$kid] = 'Karigar#'.$kid; $MACHINE_SET[(int)$mc] = true; }; $got=false; /* A) MySQL 8 — JSON_TABLE */ if (!_is_maria($pdo)) { try{ $sql = "SELECT le.machine_id, jt.karigar_id AS kid, jt.dte, jt.meter FROM loom_production_entry le JOIN JSON_TABLE(le.lines_json, '$[*]' COLUMNS( karigar_id INT PATH '$.karigar_id', meter DECIMAL(10,2) PATH '$.meter', dte DATE PATH '$.date' ) ) jt WHERE le.company_id = :cid ".($khata_id>0 ? "AND le.khata_id = :khata " : "")." ".($machine_id>0? "AND le.machine_id = :mc " : "")." ".($karigar_id>0? "AND jt.karigar_id = :kid " : "")." AND jt.dte BETWEEN :d1 AND :d2 ORDER BY jt.dte, le.machine_id, le.id"; $p=[ ':cid'=>$company_id, ':d1'=>$date_from, ':d2'=>$date_to ]; if($khata_id>0) $p[':khata']=$khata_id; if($machine_id>0) $p[':mc']=$machine_id; if($karigar_id>0) $p[':kid']=$karigar_id; $st=$pdo->prepare($sql); $st->execute($p); $hit=0; foreach($st as $r){ $d=(string)$r['dte']; $kid=(int)$r['kid']; $m=(float)$r['meter']; $mc=(int)$r['machine_id']; if($kid<=0 || $m<=0 || $d==='') continue; $accum($d,$kid,$m,$mc); $hit++; } if($hit>0) $got=true; }catch(Throwable $e){ /* go to B */ } } /* B) MariaDB — WITH RECURSIVE / no-CTE generator */ if(!$got && _is_maria($pdo)){ $p=[ ':cid'=>$company_id, ':d1'=>$date_from, ':d2'=>$date_to ]; if($khata_id>0) $p[':khata']=$khata_id; if($machine_id>0) $p[':mc']=$machine_id; if($karigar_id>0) $p[':kid']=$karigar_id; $cte = " WITH RECURSIVE seq(n) AS (SELECT 0 UNION ALL SELECT n+1 FROM seq WHERE n < 999) SELECT le.machine_id, CAST(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',seq.n,'].karigar_id'))) AS UNSIGNED) AS kid, DATE(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',seq.n,'].date')))) AS dte, CAST(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',seq.n,'].meter'))) AS DECIMAL(10,2)) AS meter FROM loom_production_entry le JOIN seq ON seq.n < JSON_LENGTH(le.lines_json) WHERE le.company_id = :cid ".($khata_id>0 ? "AND le.khata_id = :khata " : "")." ".($machine_id>0? "AND le.machine_id = :mc " : "")." ".($karigar_id>0? "AND CAST(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',seq.n,'].karigar_id'))) AS UNSIGNED) = :kid " : "")." AND DATE(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',seq.n,'].date')))) BETWEEN :d1 AND :d2 ORDER BY dte, le.machine_id"; try{ $st=$pdo->prepare($cte); $st->execute($p); $hit=0; foreach($st as $r){ $d=(string)$r['dte']; $kid=(int)$r['kid']; $m=(float)$r['meter']; $mc=(int)$r['machine_id']; if($kid<=0 || $m<=0 || $d==='') continue; $accum($d,$kid,$m,$mc); $hit++; } if($hit>0) $got=true; }catch(Throwable $e){ try{ $nocte = " SELECT le.machine_id, CAST(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',n.n,'].karigar_id'))) AS UNSIGNED) AS kid, DATE(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',n.n,'].date')))) AS dte, CAST(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',n.n,'].meter'))) AS DECIMAL(10,2)) AS meter FROM loom_production_entry le JOIN ( SELECT a.i + 10*b.i + 100*c.i AS n FROM (SELECT 0 i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a CROSS JOIN (SELECT 0 i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b CROSS JOIN (SELECT 0 i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c ) n ON n.n < JSON_LENGTH(le.lines_json) WHERE le.company_id = :cid ".($khata_id>0 ? "AND le.khata_id = :khata " : "")." ".($machine_id>0? "AND le.machine_id = :mc " : "")." ".($karigar_id>0? "AND CAST(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',n.n,'].karigar_id'))) AS UNSIGNED) = :kid " : "")." AND DATE(JSON_UNQUOTE(JSON_EXTRACT(le.lines_json, CONCAT('[$',n.n,'].date')))) BETWEEN :d1 AND :d2 ORDER BY dte, le.machine_id"; $st=$pdo->prepare($nocte); $st->execute($p); $hit=0; foreach($st as $r){ $d=(string)$r['dte']; $kid=(int)$r['kid']; $m=(float)$r['meter']; $mc=(int)$r['machine_id']; if($kid<=0 || $m<=0 || $d==='') continue; $accum($d,$kid,$m,$mc); $hit++; } if($hit>0) $got=true; }catch(Throwable $e2){ /* fall to PHP */ } } } /* C) PHP fallback — header-window (-31 days) + JSON decode */ if(!$got){ $hdr_from = date('Y-m-d', strtotime($date_from.' -31 days')); $hdr_to = $date_to; $args = [$company_id,$hdr_from,$hdr_to]; $wh = "company_id=? AND entry_date BETWEEN ? AND ?"; if ($khata_id>0){ $wh.=" AND khata_id=?"; $args[]=$khata_id; } if ($machine_id>0){ $wh.=" AND machine_id=?"; $args[]=$machine_id; } $st = $pdo->prepare("SELECT entry_date, machine_id, lines_json FROM loom_production_entry WHERE $wh ORDER BY entry_date, id"); $st->execute($args); foreach($st as $r){ $row_entry = substr((string)$r['entry_date'],0,10); if(!preg_match('/^\d{4}-\d{2}-\d{2}$/',$row_entry)) $row_entry = date('Y-m-d', strtotime($r['entry_date'])); $arr = json_decode((string)$r['lines_json'], true); if(!$arr) continue; if (isset($arr['karigar_id']) || isset($arr['meter'])) $arr = [$arr]; foreach($arr as $ln){ $kid=(int)($ln['karigar_id']??0); if($karigar_id>0 && $kid!==$karigar_id) continue; $m=(float)($ln['meter']??0); if($kid<=0 || $m<=0) continue; $d = _norm_date($ln['date'] ?? '') ?: $row_entry; $ts = strtotime($d); if(!$ts){ $_skipped_bad_date++; $ts = strtotime($row_entry); } if($ts<$from_ts || $ts>$to_ts){ $_skipped_out_range++; continue; } $accum(date('Y-m-d',$ts), $kid, $m, (int)$r['machine_id']); } } } /* Ensure every date shows (even if empty) */ foreach($DATES as $d){ if (!isset($DAY[$d])) $DAY[$d]=[]; } /* Machines for header meta */ $MACHINES = array_keys($MACHINE_SET); sort($MACHINES); /* Decide table columns (karigar list) */ $COL_KARIGARS = []; if ($karigar_id>0) { $COL_KARIGARS = [$karigar_id]; } else { $COL_KARIGARS = array_keys($ALL_KARIGARS_SET); usort($COL_KARIGARS, function($a,$b) use($KNAME_BY_ID){ return strcasecmp($KNAME_BY_ID[$a]??('K#'.$a), $KNAME_BY_ID[$b]??('K#'.$b)); }); } /* ---------- [6A] Machine dropdown options ---------- */ $MACHINE_OPTIONS = []; if ($khata_id>0 && isset($KHATA_MAP[$khata_id]['from'],$KHATA_MAP[$khata_id]['to'])){ $from = (int)$KHATA_MAP[$khata_id]['from']; $to = (int)$KHATA_MAP[$khata_id]['to']; if ($from>0 && $to>=$from){ for($i=$from;$i<=$to;$i++) $MACHINE_OPTIONS[] = $i; } } if (empty($MACHINE_OPTIONS)){ $qq = $pdo->prepare("SELECT DISTINCT machine_id FROM loom_production_entry WHERE company_id=? ORDER BY machine_id ASC"); $qq->execute([$company_id]); foreach($qq->fetchAll(PDO::FETCH_ASSOC) as $rr){ $MACHINE_OPTIONS[] = (int)$rr['machine_id']; } } $MACHINE_OPTIONS = array_values(array_unique(array_filter($MACHINE_OPTIONS, fn($x)=>$x>0))); sort($MACHINE_OPTIONS); /* ---------- [7] CSV export (Taka column removed) ---------- */ if ($do_csv){ header('Content-Type: text/csv; charset=utf-8'); $kar_lbl = ($karigar_id>0 ? $karigar_id : 'ALL'); $mc_lbl = ($machine_id>0 ? ('_MC'.$machine_id) : ''); header('Content-Disposition: attachment; filename=loom_patia_machine_daily_'.$kar_lbl.$mc_lbl.'_'.$month_str.'_H'.$half.'.csv'); $out = fopen('php://output','w'); $head = ['Date']; foreach($COL_KARIGARS as $kid){ $head[] = $KNAME_BY_ID[$kid] ?? ('Karigar#'.$kid); } fputcsv($out,$head); foreach($DATES as $d){ $row = [date('d-m-Y', strtotime($d))]; foreach($COL_KARIGARS as $kid){ $val = (float)($DAY[$d][$kid] ?? 0); $row[] = n($val,0); } fputcsv($out,$row); } $tot = ['Total']; foreach($COL_KARIGARS as $kid){ $tot[] = n($KARIGAR_TOTALS[$kid]??0,0); } fputcsv($out,$tot); fclose($out); exit; } /* ---------- [8] UI ---------- */ $MM_GREEN='#34A853'; $MM_BG='#F5FFF7'; $MM_STONE='#5F6368'; $period_lbl = sprintf('%s (Half %d) [%s ➜ %s]', $month_str, $half, $date_from, $date_to); $KNAME_HDR = ($karigar_id>0 ? ($KNAME_BY_ID[$karigar_id] ?? 'Karigar#'.$karigar_id) : 'All Karigars'); /* Chips for selected machine: unique karigars + totals (desc) */ $KARIGAR_CHIPS_HTML = ''; if ($machine_id>0 && !empty($KARIGAR_TOTALS)){ arsort($KARIGAR_TOTALS); $chips = []; foreach($KARIGAR_TOTALS as $kid=>$mtr){ $nm = $KNAME_BY_ID[$kid] ?? ('Karigar#'.$kid); $chips[] = '<span class="kchip">'.h($nm).' — '.h(n($mtr,0)).' m</span>'; } $KARIGAR_CHIPS_HTML = implode(' ', $chips); } ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Patia — Machine-wise (Daily)</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,'Helvetica Neue',Arial;margin:0;background:<?=h($MM_BG)?>;color:#222;} .wrap{max-width:1280px;margin:20px auto;padding:0 16px;} .card{background:#fff;border-radius:10px;box-shadow:0 4px 14px rgba(0,0,0,.06);padding:14px 16px;margin-bottom:14px;} .row{display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end} .field{display:flex;flex-direction:column;min-width:160px} label{font-size:12px;color:<?=$MM_STONE?>;margin-bottom:4px} select,input[type="month"]{padding:8px 10px;border:1px solid #ddd;border-radius:8px} .btn{background:<?=$MM_GREEN?>;color:#fff;border:none;border-radius:8px;padding:10px 14px;cursor:pointer} .btn-outline{background:#fff;color:<?=$MM_GREEN?>;border:1px solid <?=$MM_GREEN?>} .pill{display:inline-block;padding:6px 10px;background:#eaf7ee;border-radius:999px;color:#0b6e2b;font-size:12px;margin-left:6px} .muted{color:<?=$MM_STONE?>} table{width:100%;border-collapse:separate;border-spacing:0;margin-top:10px} thead th{background:#f7f7f7;position:sticky;top:0;z-index:2} th,td{border-bottom:1px solid #eee;padding:8px 10px;text-align:center;white-space:nowrap} th:first-child,td:first-child{text-align:left} .zero{color:#d00; font-weight:600;} .klist{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px} .kchip{display:inline-block;padding:6px 10px;background:#eef6ff;border:1px solid #dfe9ff;border-radius:999px;font-size:12px} @media print{ .no-print{display:none !important;} body{background:#fff;} .wrap{max-width:100%;margin:0;padding:0;} .card{box-shadow:none;border-radius:0;margin:0;padding:0;} thead{display:table-header-group} tfoot{display:table-footer-group} } </style> </head> <body> <div class="wrap"> <div class="card no-print"> <form class="row" method="get" id="filterForm"> <!-- Khata --> <div class="field"> <label>Khata</label> <select name="khata_id" id="khata"> <option value="0">All Khata</option> <?php foreach($KHATAS as $k): ?> <option value="<?=h($k['id'])?>" <?= $khata_id===(int)$k['id']?'selected':''?>> <?=h($k['code'])?> — <?=h($k['name'])?> </option> <?php endforeach; ?> </select> </div> <!-- Karigar (optional; hidden if mapped karigar login) --> <?php if(!($role==='karigar' && $self_karigar_id>0)): ?> <div class="field"> <label>Karigar</label> <select name="karigar_id" id="karigar"> <option value="0" <?= $karigar_id===0?'selected':''?>>All Karigars</option> <?php foreach($KARIGAR_LIST as $k): ?> <option value="<?=h($k['id'])?>" <?= $karigar_id===$k['id']?'selected':''?>><?=h($k['name'])?></option> <?php endforeach; ?> </select> </div> <?php else: ?> <input type="hidden" name="karigar_id" value="<?=h($karigar_id)?>"> <div class="field"> <label>Karigar</label> <div class="pill">Your Data</div> </div> <?php endif; ?> <!-- Machine --> <div class="field"> <label>Machine</label> <select name="machine_id" id="machine"> <option value="0" <?= $machine_id===0?'selected':''; ?>>All Machines</option> <?php foreach($MACHINE_OPTIONS as $mc): ?> <option value="<?=h($mc)?>" <?= $machine_id===$mc?'selected':''?>>MC <?=h($mc)?></option> <?php endforeach; ?> </select> </div> <div class="field"> <label>Month</label> <input type="month" name="month" value="<?=h($month_str)?>"> </div> <div class="field"> <label>Half</label> <select name="half"> <option value="1" <?= $half===1?'selected':''?>>1–15</option> <option value="2" <?= $half===2?'selected':''?>>16–End</option> </select> </div> <div class="field"> <button class="btn" type="submit">Apply</button> </div> <div class="field"> <a class="btn btn-outline" href="?<?=http_build_query([ 'khata_id'=>$khata_id,'karigar_id'=>$karigar_id,'machine_id'=>$machine_id,'month'=>$month_str,'half'=>$half,'csv'=>1 ])?>">Export CSV</a> </div> <div class="field"><button type="button" class="btn" onclick="window.print()">Print</button></div> <div class="field"><button type="button" class="btn btn-outline" onclick="window.print()">PDF</button></div> <div style="margin-left:auto" class="muted"> Period: <span class="pill"><?=h($period_lbl)?></span> </div> </form> </div> <div class="card"> <div style="text-align:center;margin-bottom:8px"> <div style="font-weight:700">Machine-wise Patia (Daily)</div> <div class="muted"><?=h(date('F-Y', strtotime($month_str.'-01')))?> · <?= $machine_id>0 ? 'Machine MC '.h($machine_id) : 'All Machines' ?></div> </div> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px"> <div> <?php if($khata_id>0): ?><span class="pill">Khata <?=h($KHATA_MAP[$khata_id]['code']??$khata_id)?></span><?php endif; ?> <?php if($karigar_id>0): ?><span class="pill"><?=h($KNAME_BY_ID[$karigar_id] ?? 'Karigar')?></span><?php endif; ?> <?php if($machine_id>0): ?><span class="pill">MC <?=h($machine_id)?></span><?php endif; ?> </div> <div class="muted no-print">Machines: <?= ($machine_id>0 ? 1 : count($MACHINES)) ?> | Days: <?=count($DATES)?></div> </div> <?php if($machine_id>0): ?> <div class="klist no-print" style="margin-bottom:8px"> <?php if ($KARIGAR_CHIPS_HTML!=='') echo $KARIGAR_CHIPS_HTML; else echo '<span class="muted">No karigar data for this machine in selected period.</span>'; ?> </div> <?php endif; ?> <div style="overflow:auto;max-height:70vh"> <table> <thead> <tr> <th style="min-width:120px">Date</th> <?php foreach($COL_KARIGARS as $kid): ?> <th><?=h($KNAME_BY_ID[$kid] ?? ('Karigar#'.$kid))?></th> <?php endforeach; ?> </tr> </thead> <tbody> <?php foreach($DATES as $d): ?> <tr> <td><?=h(date('d-m-Y', strtotime($d)))?></td> <?php foreach($COL_KARIGARS as $kid): $val = (float)($DAY[$d][$kid] ?? 0); if ($val>0): ?> <td><?= n($val,0) ?></td> <?php else: ?> <td class="zero">0</td> <?php endif; endforeach; ?> </tr> <?php endforeach; ?> </tbody> <tfoot> <tr> <td><strong>Total</strong></td> <?php foreach($COL_KARIGARS as $kid): ?> <td><strong><?= n($KARIGAR_TOTALS[$kid]??0,0) ?></strong></td> <?php endforeach; ?> </tr> </tfoot> </table> </div> </div> </div> </body> </html>