« Back to History
saree_setwise.php
|
20260722_120325.php
Initial Domain Snapshot
Copy Code
<?php // saree_setwise.php // Show set-wise "equalize" report for a selected quality. // Expects modules/auth/page_acl.php bootstrap providing page_require_access and $ctx['pdo']. // DOES NOT create tables. Uses existing saree_stock_in and saree_stock_out tables (company-scoped). // ---------------- bootstrap ---------------- $acl_candidates = [ __DIR__ . '/modules/auth/page_acl.php', __DIR__ . '/../modules/auth/page_acl.php', __DIR__ . '/../../modules/auth/page_acl.php', ]; $acl_loaded = false; foreach ($acl_candidates as $p) { if (is_file($p)) { require_once $p; $acl_loaded = true; break; } } if (!$acl_loaded) { header('Content-Type: text/plain; charset=utf-8', true, 500); echo "Missing modules/auth/page_acl.php - cannot continue."; exit; } $ctx = page_require_access('saree_setwise'); $pdo = $ctx['pdo'] ?? null; $company_id = (int)($ctx['company_id'] ?? 0); $user = $ctx['user'] ?? null; if (!$pdo) { echo "<h2>Database connection not available (ctx['pdo'] missing)</h2>"; exit; } function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } // company name $company_name = ''; if (!empty($ctx['company_name'])) $company_name = (string)$ctx['company_name']; elseif (!empty($ctx['company']['name'])) $company_name = (string)$ctx['company']['name']; else { try { $q = $pdo->prepare("SELECT name FROM companies WHERE id = :cid LIMIT 1"); $q->execute([':cid'=>$company_id]); $r = $q->fetch(PDO::FETCH_ASSOC); if ($r && !empty($r['name'])) $company_name = $r['name']; } catch (Exception $e) { /* ignore */ } if ($company_name === '') $company_name = 'Company #' . ($company_id ?: '1'); } // GET params $quality = trim($_GET['quality'] ?? ''); $show = isset($_GET['show']) || $quality !== ''; // helper include header/footer function require_first_existing(array $paths) { foreach ($paths as $p) { if (is_file($p)) { require_once $p; return true; } } return false; } $header_candidates = [ __DIR__ . '/erp/partials/header.php', __DIR__ . '/partials/header.php', __DIR__ . '/../erp/partials/header.php', __DIR__ . '/../../erp/partials/header.php', ]; $footer_candidates = [ __DIR__ . '/erp/partials/footer.php', __DIR__ . '/partials/footer.php', __DIR__ . '/../erp/partials/footer.php', __DIR__ . '/../../erp/partials/footer.php', ]; // If show requested, compute the setwise data $rows = []; // will hold rows: design, dn_no, dname, color, current_qty $designs = []; // unique designs list $colors = []; // unique colors list $byDesign = []; // byDesign[design] = ['colors' => [color=>qty], 'max'=>int, 'total'=>int] if ($show && $quality !== '') { // Build aggregated net qty per design+color using union all and grouping. // net = sum(in_qty) - sum(out_qty) $sql = " SELECT design, color, SUM(net_qty) AS qty FROM ( SELECT design, color, saree_qty AS net_qty FROM saree_stock_in WHERE company_id = :cid AND quality = :quality UNION ALL SELECT design, color, -saree_qty AS net_qty FROM saree_stock_out WHERE company_id = :cid AND quality = :quality ) t GROUP BY design, color ORDER BY design, color "; $stmt = $pdo->prepare($sql); $stmt->execute([':cid'=>$company_id, ':quality'=>$quality]); $all = $stmt->fetchAll(PDO::FETCH_ASSOC); // Sometimes some design/color combos are absent; but above gives all combos that exist. // We'll collect unique designs and colors and organize per design. foreach ($all as $r) { $design = trim((string)$r['design']); $color = trim((string)$r['color']); $qty = (int)$r['qty']; if ($design === '') $design = '(No Design)'; if ($color === '') $color = '(No Color)'; $designs[$design] = true; $colors[$color] = true; $byDesign[$design]['colors'][$color] = ($byDesign[$design]['colors'][$color] ?? 0) + $qty; $byDesign[$design]['total'] = ($byDesign[$design]['total'] ?? 0) + $qty; } // For completeness: ensure every design has entries for all colors (if you want zeros) // But better to compute max per design based on available colors for that design only. foreach ($byDesign as $design => $info) { $max = 0; foreach ($info['colors'] as $c => $q) { if ($q > $max) $max = $q; } $byDesign[$design]['max'] = $max; // compute required per color foreach ($info['colors'] as $c => $q) { $req = $max - $q; if ($req < 0) $req = 0; $byDesign[$design]['required'][$c] = $req; } } } // prepare arrays sorted $designs_list = array_keys($designs); $colors_list = array_keys($colors); sort($designs_list); sort($colors_list); // ---------------- Render HTML ---------------- ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Setwise Report - <?php echo h($quality ?: '—'); ?></title> <meta name="viewport" content="width=device-width,initial-scale=1"> <style> body{font-family:Arial,Helvetica,sans-serif;background:#fff;color:#222;margin:16px} .wrap{max-width:1100px;margin:0 auto} .no-print{display:block} .hdr{text-align:center;margin-bottom:10px} .hdr h2{margin:6px 0} .controls{display:flex;gap:8px;align-items:center;margin-bottom:12px;flex-wrap:wrap} label{font-size:14px;color:#333} select,input[type=date]{padding:8px;border-radius:6px;border:1px solid #ddd} button{padding:8px 12px;border-radius:6px;border:none;background:#2fbe4a;color:#fff;cursor:pointer} button.secondary{background:#3498db} table{width:100%;border-collapse:collapse;margin-top:10px;font-size:13px} table th{background:#4f5b61;color:#fff;padding:8px;border:1px solid #e0e0e0;text-align:left} table td{padding:6px;border:1px solid #eaeaea;text-align:right} td.left{text-align:left} .design-row { background:#f6f8fa; font-weight:600; } .small{font-size:12px;color:#666} @media print { .no-print{display:none !important} body{margin:0} } </style> </head> <body> <!-- optional header include (screen only) --> <div class="no-print"><?php require_first_existing($header_candidates); ?></div> <div class="wrap"> <div class="hdr"> <h2><?php echo h($company_name); ?> — Setwise Requirement Report</h2> <div class="small">Quality: <strong><?php echo h($quality ?: '—'); ?></strong> | Date: <?php echo date('d-M-Y'); ?></div> </div> <div class="no-print controls"> <form method="get" style="display:flex;gap:8px;align-items:center"> <label for="quality">Quality</label> <input type="text" name="quality" id="quality" value="<?php echo h($quality); ?>" placeholder="Enter quality (e.g., GP)"> <button type="submit" name="show" value="1">Show</button> </form> <div style="margin-left:auto;display:flex;gap:8px"> <button id="btn-print">Print</button> <button id="btn-pdf" class="secondary">Export PDF</button> <button id="btn-csv">Export CSV</button> <a href="/erp/saree_stock_repot.php?quality=<?php echo urlencode($quality); ?>"><button class="secondary" type="button">Back to Stock Report</button></a> </div> </div> <?php if (!$show || $quality === ''): ?> <div class="small">Provide a quality and click Show to view setwise requirements.</div> <?php else: ?> <?php if (empty($byDesign)): ?> <div>No stock data found for quality <?php echo h($quality); ?>.</div> <?php else: ?> <div id="report-area"> <table id="report-table" aria-describedby="report-summary"> <thead> <tr> <th style="width:160px">D.N NO</th> <th>Design Name</th> <th style="width:110px">Color</th> <th style="width:110px">Current</th> <th style="width:110px">Max</th> <th style="width:120px">Required</th> </tr> </thead> <tbody> <?php $grandCurrent = 0; $grandRequired = 0; foreach ($designs_list as $design): $dn_no = ''; $dname = $design; if (strpos($design,'|') !== false) { $p = explode('|',$design,2); $dn_no = trim($p[0]); $dname = trim($p[1]); } $info = $byDesign[$design] ?? ['colors'=>[],'max'=>0,'total'=>0]; // design header row ?> <tr class="design-row"> <td class="left"><?php echo h($dn_no); ?></td> <td class="left"><?php echo h($dname); ?></td> <td style="text-align:center">--</td> <td style="text-align:center"><?php echo h($info['total'] ?? 0); ?></td> <td style="text-align:center"><?php echo h($info['max'] ?? 0); ?></td> <td style="text-align:center"> <?php $reqSum = array_sum($info['required'] ?? []); echo h($reqSum); $grandCurrent += ($info['total'] ?? 0); $grandRequired += $reqSum; ?> </td> </tr> <?php // show each color line under design foreach (($info['colors'] ?? []) as $color => $curQty): $max = $info['max'] ?? 0; $req = ($max - $curQty); if ($req < 0) $req = 0; ?> <tr> <td></td> <td class="left"></td> <td class="left"><?php echo h($color); ?></td> <td><?php echo h($curQty === 0 ? '' : $curQty); ?></td> <td><?php echo h($max === 0 ? '' : $max); ?></td> <td><?php echo h($req === 0 ? '' : $req); ?></td> </tr> <?php endforeach; ?> <?php endforeach; ?> </tbody> <tfoot> <tr> <th colspan="3" style="text-align:right">Grand Totals</th> <th style="text-align:center"><?php echo h($grandCurrent); ?></th> <th></th> <th style="text-align:center"><?php echo h($grandRequired); ?></th> </tr> </tfoot> </table> </div> <?php endif; ?> <?php endif; ?> </div> <!-- footer include (screen only) --> <div class="no-print"><?php require_first_existing($footer_candidates); ?></div> <!-- html2pdf CDN for PDF export --> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.9.3/html2pdf.bundle.min.js"></script> <script> (function(){ const btnPrint = document.getElementById('btn-print'); const btnPdf = document.getElementById('btn-pdf'); const btnCsv = document.getElementById('btn-csv'); const reportArea = document.getElementById('report-area'); const reportTable = document.getElementById('report-table'); if (btnPrint) btnPrint.addEventListener('click', ()=> window.print()); if (btnPdf) btnPdf.addEventListener('click', ()=> { if (!reportArea) return alert('No report to export'); if (typeof html2pdf !== 'undefined') { const opt = { margin: 10, filename: 'saree_setwise_<?php echo date("Ymd"); ?>.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2 }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }; html2pdf().set(opt).from(reportArea).save(); } else { window.print(); } }); if (btnCsv) btnCsv.addEventListener('click', ()=> { if (!reportTable) return alert('No report to export'); // build CSV let csv = ''; const rows = reportTable.querySelectorAll('tr'); rows.forEach(r => { const cols = r.querySelectorAll('th,td'); const row = []; cols.forEach(c => { let txt = c.innerText.replace(/\n/g,' ').trim(); if (txt.indexOf('"') !== -1) txt = txt.replace(/"/g,'""'); if (txt.indexOf(',') !== -1 || txt.indexOf('"') !== -1) txt = '"' + txt + '"'; row.push(txt); }); csv += row.join(',') + '\n'; }); const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const fname = 'saree_setwise_<?php echo date("Ymd"); ?>.csv'; if (navigator.msSaveBlob) { navigator.msSaveBlob(blob, fname); } else { const link = document.createElement('a'); const url = URL.createObjectURL(blob); link.setAttribute('href', url); link.setAttribute('download', fname); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } }); })(); </script> </body> </html>