« Back to History
patia.php
|
20260723_000646.php
Initial Domain Snapshot
Copy Code
<?php /* ============================================================================= Machine-wise Loom Production Report (Half-month, Karigar-wise grid) lines_json now has per-line {"karigar_id","meter","date"} Fix: columns from data (even if names missing). Added debug panel. Scope: Page-local only. Multi-company aware. No global/base changes. ============================================================================= */ error_reporting(E_ALL); ini_set('display_errors', 1); /* [1] AUTH & PDO */ require __DIR__ . '/../modules/auth/auth.php'; require_login(); $u = auth_user(); $company_id = (int)$u['company_id']; $pdo = $GLOBALS['pdo'] ?? null; if (!$pdo) { require __DIR__ . '/../core/db.php'; } /* [2] HELPERS */ function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function half_month_range(int $y,int $m,int $half){ $start=sprintf('%04d-%02d-%02d',$y,$m,$half===1?1:16); $end=sprintf('%04d-%02d-%02d',$y,$m,$half===1?15:(int)date('t',strtotime("$y-$m-01"))); return [$start,$end]; } function date_list($s,$e){ $o=[];$t=strtotime($s);$E=strtotime($e); while($t<=$E){ $o[]=date('Y-m-d',$t); $t=strtotime('+1 day',$t);} return $o; } function load_machines(PDO $pdo,int $co){ foreach ([ "SELECT id,machine_no,khata_id FROM machines WHERE company_id=? ORDER BY machine_no", "SELECT id,code AS machine_no,khata_id FROM machines WHERE company_id=? ORDER BY code", ] as $sql){ try{$st=$pdo->prepare($sql);$st->execute([$co]);$r=$st->fetchAll(PDO::FETCH_ASSOC); if($r) return $r;}catch(Throwable $e){} } try{ $st=$pdo->prepare("SELECT DISTINCT machine_id AS id, machine_id AS machine_no, NULL AS khata_id FROM loom_production_entry WHERE company_id=? ORDER BY machine_id"); $st->execute([$co]); return $st->fetchAll(PDO::FETCH_ASSOC);}catch(Throwable $e){return[];} } function load_khatas(PDO $pdo,int $co){ foreach ([ "SELECT id,name,machine_from,machine_to FROM khatas WHERE company_id=? ORDER BY id", "SELECT id,name,machine_from,machine_to FROM khata WHERE company_id=? ORDER BY id", ] as $sql){ try{$st=$pdo->prepare($sql);$st->execute([$co]);$r=$st->fetchAll(PDO::FETCH_ASSOC); if($r) return $r;}catch(Throwable $e){} } try{ $st=$pdo->prepare("SELECT DISTINCT khata_id AS id FROM machines WHERE company_id=? AND khata_id IS NOT NULL ORDER BY khata_id"); $st->execute([$co]); $r=$st->fetchAll(PDO::FETCH_ASSOC); if($r){foreach($r as &$x){$x+=['name'=>"Khata ".$x['id'],'machine_from'=>null,'machine_to'=>null];} return $r;} }catch(Throwable $e){} try{ $st=$pdo->prepare("SELECT DISTINCT khata_id AS id FROM loom_production_entry WHERE company_id=? AND khata_id IS NOT NULL ORDER BY khata_id"); $st->execute([$co]); $r=$st->fetchAll(PDO::FETCH_ASSOC); if($r){foreach($r as &$x){$x+=['name'=>"Khata ".$x['id'],'machine_from'=>null,'machine_to'=>null];} return $r;} }catch(Throwable $e){} return []; } function karigar_names(PDO $pdo,int $co,array $ids):array{ $ids=array_values(array_unique(array_map('intval',$ids))); if(!$ids) return []; $in=implode(',',array_fill(0,count($ids),'?')); try{ $st=$pdo->prepare("SELECT id,name FROM employees WHERE company_id=? AND id IN ($in)"); $st->execute(array_merge([$co],$ids)); $m=[]; foreach($st as $r){$m[(int)$r['id']]=$r['name'];} if($m) return $m; }catch(Throwable $e){} try{ $st=$pdo->prepare("SELECT id,name FROM users WHERE company_id=? AND id IN ($in)"); $st->execute(array_merge([$co],$ids)); $m=[]; foreach($st as $r){$m[(int)$r['id']]=$r['name'];} return $m; }catch(Throwable $e){ return []; } } function norm_line_date($val,int $Y,int $M,$row_entry){ $s=is_string($val)||is_int($val)?trim((string)$val):''; if($s===''){ return $row_entry?:''; } if(preg_match('/^\d{4}-\d{2}-\d{2}$/',$s)) return $s; if(preg_match('/^\d{1,2}$/',$s)){ $d=max(1,min(31,(int)$s)); $last=(int)date('t',strtotime("$Y-$M-01")); $d=min($d,$last); return sprintf('%04d-%02d-%02d',$Y,$M,$d); } $t=strtotime($s); return $t?date('Y-m-d',$t):($row_entry?:''); } /* [3] FILTERS + DEBUG */ $debug = isset($_GET['debug']) ? 1 : 0; $dbg = ['filters'=>[], 'sql'=>null, 'params'=>[], 'row_count'=>0, 'parsed_lines'=>0, 'skips'=>['no_kid'=>0,'no_mtr'=>0,'no_date'=>0,'out_of_half'=>0,'khata_mismatch_rows'=>0,'json_error_rows'=>0], 'karigars'=>[], 'dates'=>[]]; $khatas = load_khatas($pdo,$company_id); $machines = load_machines($pdo,$company_id); $sel_khata = isset($_GET['khata_id']) ? (int)$_GET['khata_id'] : ( $khatas[0]['id'] ?? 0 ); $sel_machine = isset($_GET['machine_id']) ? (int)$_GET['machine_id'] : ( $machines[0]['id'] ?? 0 ); $sel_year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y'); $sel_month = isset($_GET['month']) ? (int)$_GET['month'] : (int)date('n'); $sel_half = isset($_GET['half']) ? (int)$_GET['half'] : 1; [$from_date,$to_date] = half_month_range($sel_year,$sel_month,$sel_half); $month_start = sprintf('%04d-%02d-01',$sel_year,$sel_month); $month_end = sprintf('%04d-%02d-%02d',$sel_year,$sel_month,(int)date('t',strtotime($month_start))); $dbg['filters'] = compact('sel_khata','sel_machine','sel_year','sel_month','sel_half','from_date','to_date','month_start','month_end'); /* [4] READ & AGGREGATE (line-level date) */ $matrix=[]; $kar_ids=[]; try{ $sql = "SELECT entry_date,khata_id,lines_json FROM loom_production_entry WHERE company_id=? AND machine_id=? AND entry_date BETWEEN ? AND ?"; $params = [$company_id,$sel_machine,$month_start,$month_end]; if ($sel_khata) { $sql .= " AND (khata_id=? OR khata_id IS NULL)"; $params[]=$sel_khata; } $sql .= " ORDER BY entry_date"; $dbg['sql']=$sql; $dbg['params']=$params; $st=$pdo->prepare($sql); $st->execute($params); while($r=$st->fetch(PDO::FETCH_ASSOC)){ $dbg['row_count']++; $row_khata = (int)($r['khata_id'] ?? 0); $row_entry = $r['entry_date'] ?? ''; $arr = json_decode((string)$r['lines_json'], true); if (!is_array($arr)) { $dbg['skips']['json_error_rows']++; continue; } foreach($arr as $ln){ $kid = isset($ln['karigar_id']) ? (int)$ln['karigar_id'] : 0; $mtr = isset($ln['meter']) ? (float)$ln['meter'] : 0.0; $ld = norm_line_date($ln['date'] ?? '', $sel_year,$sel_month,$row_entry); if ($kid<=0){ $dbg['skips']['no_kid']++; continue; } if ($mtr<=0){ $dbg['skips']['no_mtr']++; continue; } if (!$ld){ $dbg['skips']['no_date']++; continue; } // Half filter applies on line date: if ($ld < $from_date || $ld > $to_date){ $dbg['skips']['out_of_half']++; continue; } if (!isset($matrix[$ld])) $matrix[$ld]=[]; $matrix[$ld][$kid] = ($matrix[$ld][$kid] ?? 0) + $mtr; $kar_ids[] = $kid; $dbg['parsed_lines']++; } } }catch(Throwable $e){ $dbg['error'] = $e->getMessage(); } /* Build columns from DATA (fix) */ $kar_cols = array_values(array_unique($kar_ids)); sort($kar_cols); /* Names map (optional) */ $kar_map = karigar_names($pdo,$company_id,$kar_cols); $missing = array_values(array_diff($kar_cols, array_keys($kar_map))); $dbg['karigars'] = ['ids'=>$kar_cols,'names_found'=>array_keys($kar_map),'missing'=>$missing]; $dates = date_list($from_date,$to_date); $dbg['dates'] = ['count'=>count($dates),'first'=>$dates[0]??null,'last'=>end($dates)?:null]; /* [5] HTML */ ?> <!doctype html> <html> <head> <meta charset="utf-8"> <title>Machine-wise Loom Production (Half-month)</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> :root{ --mm-primary:#34A853; --mm-bg:#F5FFF7; --mm-text:#333; --mm-sub:#5F6368; --mm-accent:#A7D8DE; --mm-hi:#FFF9C4; --card:#fff; --bd:#e6e6e6; } body{font-family:system-ui,Segoe UI,Roboto,Arial,sans-serif;background:var(--mm-bg);color:var(--mm-text);margin:0;padding:20px;} .wrap{max-width:1100px;margin:auto;} h1{margin:0 0 12px;font-size:22px;color:var(--mm-primary)} .card{background:var(--card);border:1px solid var(--bd);border-radius:14px;box-shadow:0 2px 10px rgba(0,0,0,.04);padding:14px;margin-bottom:16px;} .filters{display:grid;grid-template-columns:repeat(7,minmax(120px,1fr));gap:10px;align-items:end} label{font-size:12px;color:var(--mm-sub)} select,button,input[type=checkbox]{padding:8px 10px;border:1px solid var(--bd);border-radius:10px;font-size:14px;background:#fff} button{background:var(--mm-primary);color:#fff;border:none;cursor:pointer} .help{font-size:12px;color:var(--mm-sub);margin-top:6px} table{width:100%;border-collapse:collapse;margin-top:10px;font-size:14px} th,td{border:1px solid var(--bd);padding:8px;text-align:right} th.date,td.date{text-align:left;white-space:nowrap} thead th{background:var(--mm-accent);font-weight:600} tbody tr:nth-child(odd){background:#fafafa} .total{background:var(--mm-hi);font-weight:600} .pill{display:inline-block;padding:2px 8px;border-radius:999px;background:#e8f5ee;color:var(--mm-primary);font-size:12px} details.debug{font-size:12px;margin-top:10px} details.debug pre{white-space:pre-wrap;background:#fafafa;border:1px dashed var(--bd);padding:10px;border-radius:10px} </style> </head> <body> <div class="wrap"> <h1>Machine-wise Loom Production (Half-month)</h1> <div class="card"> <form method="get" class="filters"> <div> <label>Khata</label> <select name="khata_id" id="khata_id"> <?php foreach($khatas as $k): ?> <option value="<?= (int)$k['id'] ?>" <?= $sel_khata==(int)$k['id']?'selected':'' ?>><?= h($k['name'] ?? ('Khata '.$k['id'])) ?></option> <?php endforeach; ?> </select> </div> <div> <label>Machine</label> <select name="machine_id" id="machine_id"> <?php foreach($machines as $m): ?> <option value="<?= (int)$m['id'] ?>" data-khata="<?= h($m['khata_id'] ?? '') ?>" <?= $sel_machine==(int)$m['id']?'selected':'' ?>> <?= 'MC '.h($m['machine_no']) ?> </option> <?php endforeach; ?> </select> </div> <div> <label>Month</label> <select name="month"><?php $mn=[1=>"Jan",2=>"Feb",3=>"Mar",4=>"Apr",5=>"May",6=>"Jun",7=>"Jul",8=>"Aug",9=>"Sep",10=>"Oct",11=>"Nov",12=>"Dec"]; foreach($mn as $i=>$nm): ?> <option value="<?= $i ?>" <?= $sel_month==$i?'selected':'' ?>><?= $nm ?></option><?php endforeach; ?> </select> </div> <div> <label>Half</label> <select name="half"> <option value="1" <?= $sel_half==1?'selected':'' ?>>1–15</option> <option value="2" <?= $sel_half==2?'selected':'' ?>>16–EOM</option> </select> </div> <div> <label>Year</label> <select name="year"><?php foreach([date('Y')-1,date('Y'),date('Y')+1] as $yr): ?> <option value="<?= (int)$yr ?>" <?= $sel_year==$yr?'selected':'' ?>><?= (int)$yr ?></option><?php endforeach; ?> </select> </div> <div style="display:flex;align-items:center;gap:8px"> <label><input type="checkbox" name="debug" value="1" <?= $debug?'checked':'' ?> /> Show Debug</label> </div> <div> <button type="submit">Show Report</button> <div class="help">Range: <span class="pill"><?= h($from_date) ?> → <?= h($to_date) ?></span> (line-level dates)</div> </div> </form> </div> <div class="card"> <?php // totals $colTotals = array_fill_keys($kar_cols, 0.0); $grand = 0.0; ?> <table> <thead> <tr> <th class="date">Date</th> <?php foreach($kar_cols as $kid): ?> <th><?= h($kar_map[$kid] ?? ('Karigar '.$kid)) ?></th> <?php endforeach; ?> <th>Total</th> </tr> </thead> <tbody> <?php foreach($dates as $d): ?> <?php $rowTotal=0.0; ?> <tr> <td class="date"><?= date('d-M', strtotime($d)) ?></td> <?php foreach($kar_cols as $kid): $val=isset($matrix[$d][$kid])?(float)$matrix[$d][$kid]:0.0; $rowTotal+=$val; $colTotals[$kid]+=$val; $grand+=$val; ?> <td><?= $val>0 ? number_format($val,0) : '' ?></td> <?php endforeach; ?> <td class="total"><?= $rowTotal>0?number_format($rowTotal,0):'' ?></td> </tr> <?php endforeach; ?> <tr class="total"> <td class="date">Total</td> <?php foreach($kar_cols as $kid): ?> <td><?= $colTotals[$kid]>0?number_format($colTotals[$kid],0):'' ?></td> <?php endforeach; ?> <td><?= $grand>0?number_format($grand,0):'' ?></td> </tr> </tbody> </table> <?php if($debug): ?> <details class="debug" open> <summary>Debug Report</summary> <pre><?= h(json_encode($dbg, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)) ?></pre> <p style="color:#5F6368">यदि values नहीं आ रहीं: <br>• <b>karigars.missing</b> में IDs आ रही हों तो employees/users में नाम नहीं मिले—फिर भी अब कॉलम बनेंगे (fallback नाम दिखेगा)। <br>• <b>skips.out_of_half</b> > 0 हो तो line-date चुने हुए half-range में नहीं है। <br>• <b>sql</b> व <b>params</b> देखें—machine/khata filter row को बाहर तो नहीं कर रहे। <br>• <b>json_error_rows</b> > 0 हो तो lines_json खराब है (invalid JSON)।</p> </details> <?php endif; ?> </div> </div> <script> /* Machine list को Khata के हिसाब से फ़िल्टर (यदि data-khata मौजूद) */ (function(){ const selKhata=document.getElementById('khata_id'); const selMach=document.getElementById('machine_id'); if(!selKhata||!selMach) return; function applyFilter(){ const k=selKhata.value; let first=null; [...selMach.options].forEach(o=>{ const ok=!o.dataset.khata||o.dataset.khata===''||o.dataset.khata===k; o.hidden=!ok; if(ok && !first) first=o; }); if(selMach.selectedOptions[0]?.hidden && first){ first.selected=true; } } selKhata.addEventListener('change',applyFilter); applyFilter(); })(); </script> </body> </html>