getConnection(); /* 2=produzione, 3=qualità(fine ok), 7=pausa, 8=problema. "Concluse"=3,8 */ $STATI_CONCLUSI = [3, 8]; $linee = $pdo->query("SELECT id, name, color, max_hours_per_day FROM production_lines ORDER BY line_number")->fetchAll(); $matrici = $pdo->query("SELECT id, nome FROM matrice ORDER BY nome")->fetchAll(); $mescole = $pdo->query("SELECT id, nome FROM mescole ORDER BY nome")->fetchAll(); if (!empty($_GET['ajax'])) { header('Content-Type: application/json'); $dateFrom = $_GET['date_from'] ?? ''; $dateTo = $_GET['date_to'] ?? ''; $lineRaw = $_GET['lines'] ?? ''; $lineArr = $lineRaw !== '' ? array_values(array_filter(array_map('intval', explode(',', $lineRaw)))) : []; $matId = isset($_GET['matrice_id']) && $_GET['matrice_id'] !== '' ? (int)$_GET['matrice_id'] : null; $mescId = isset($_GET['mescola_id']) && $_GET['mescola_id'] !== '' ? (int)$_GET['mescola_id'] : null; $granul = ($_GET['granularity'] ?? 'day') === 'month' ? 'month' : 'day'; $where = ["p.id_status IN (" . implode(',', $STATI_CONCLUSI) . ")"]; $params = []; if ($dateFrom !== '') { $where[] = "p.Data >= :date_from"; $params['date_from'] = $dateFrom; } if ($dateTo !== '') { $where[] = "p.Data <= :date_to"; $params['date_to'] = $dateTo; } if (!empty($lineArr)) { $where[] = "p.id_linea IN (" . implode(',', $lineArr) . ")"; } if ($matId !== null) { $where[] = "p.idmatrice = :mat_id"; $params['mat_id'] = $matId; } if ($mescId !== null) { $where[] = "EXISTS (SELECT 1 FROM productiondata_mescole pm WHERE pm.id_productiondata = p.id AND pm.id_mescola = :mesc_id)"; $params['mesc_id'] = $mescId; } $whereSql = implode(' AND ', $where); try { $sqlKpi = "SELECT COUNT(*) AS n_produzioni, COALESCE(SUM(p.tempo_totale_produzione),0) AS tot_occupato_s, COALESCE(SUM(p.seconds_pause),0) AS tot_pause_s, COALESCE(SUM(p.seconds_produzione),0) AS tot_netto_s, COALESCE(SUM(p.kgprod),0) AS tot_kg, COALESCE(SUM(p.mtprod),0) AS tot_mt, COALESCE(SUM(p.scarto),0) AS tot_scarto FROM productiondata p WHERE $whereSql"; $stmt = $pdo->prepare($sqlKpi); $stmt->execute($params); $kpi = $stmt->fetch(PDO::FETCH_ASSOC); $effTempo = ($kpi['tot_occupato_s'] > 0) ? round($kpi['tot_netto_s'] / $kpi['tot_occupato_s'] * 100, 1) : 0; $denomScarto = $kpi['tot_kg'] + $kpi['tot_scarto']; $scartoPercTot = ($denomScarto > 0) ? round($kpi['tot_scarto'] / $denomScarto * 100, 2) : 0; $giorniRange = 1; if ($dateFrom !== '' && $dateTo !== '') { $d1 = new DateTime($dateFrom); $d2 = new DateTime($dateTo); $giorniRange = max(1, $d1->diff($d2)->days + 1); } $capSql = "SELECT COALESCE(SUM(max_hours_per_day),0) AS somma_ore_giorno FROM production_lines" . (!empty($lineArr) ? " WHERE id IN (" . implode(',', $lineArr) . ")" : ""); $capOreGiorno = (float)$pdo->query($capSql)->fetchColumn(); $capacitaTeoricaS = $capOreGiorno * 3600 * $giorniRange; $saturazione = ($capacitaTeoricaS > 0) ? round($kpi['tot_occupato_s'] / $capacitaTeoricaS * 100, 1) : 0; $sqlLinea = "SELECT l.id, l.name AS linea, l.color, l.max_hours_per_day, COUNT(*) AS n_prod, COALESCE(SUM(p.tempo_totale_produzione),0) AS occupato_s, COALESCE(SUM(p.seconds_pause),0) AS pause_s, COALESCE(SUM(p.seconds_produzione),0) AS netto_s, COALESCE(SUM(p.kgprod),0) AS kg, COALESCE(SUM(p.scarto),0) AS scarto FROM productiondata p JOIN production_lines l ON l.id = p.id_linea WHERE $whereSql GROUP BY l.id ORDER BY l.line_number"; $stmt = $pdo->prepare($sqlLinea); $stmt->execute($params); $perLinea = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($perLinea as &$row) { $row['eff_tempo'] = ($row['occupato_s'] > 0) ? round($row['netto_s'] / $row['occupato_s'] * 100, 1) : 0; $den = $row['kg'] + $row['scarto']; $row['scarto_perc'] = ($den > 0) ? round($row['scarto'] / $den * 100, 2) : 0; $capLineaS = (float)$row['max_hours_per_day'] * 3600 * $giorniRange; $row['saturazione'] = ($capLineaS > 0) ? round($row['occupato_s'] / $capLineaS * 100, 1) : 0; } unset($row); if ($granul === 'month') { $periodExpr = "DATE_FORMAT(p.Data, '%Y-%m')"; } else { $periodExpr = "p.Data"; } $sqlSerie = "SELECT $periodExpr AS periodo, COALESCE(SUM(p.tempo_totale_produzione),0) AS occupato_s, COALESCE(SUM(p.seconds_pause),0) AS pause_s, COALESCE(SUM(p.seconds_produzione),0) AS netto_s, COALESCE(SUM(p.kgprod),0) AS kg, COALESCE(SUM(p.scarto),0) AS scarto FROM productiondata p WHERE $whereSql GROUP BY periodo ORDER BY periodo"; $stmt = $pdo->prepare($sqlSerie); $stmt->execute($params); $serie = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($serie as &$s) { $s['eff_tempo'] = ($s['occupato_s'] > 0) ? round($s['netto_s'] / $s['occupato_s'] * 100, 1) : 0; $den = $s['kg'] + $s['scarto']; $s['scarto_perc'] = ($den > 0) ? round($s['scarto'] / $den * 100, 2) : 0; } unset($s); $sqlCat = "SELECT pr.category AS category, COALESCE(SUM(TIMESTAMPDIFF(SECOND, pp.start_pause, pp.end_pause)),0) AS durata_s FROM production_pauses pp JOIN productiondata p ON p.id = pp.id_production JOIN pause_reasons pr ON pr.id = pp.reason_id WHERE pp.end_pause IS NOT NULL AND $whereSql GROUP BY pr.category"; $stmt = $pdo->prepare($sqlCat); $stmt->execute($params); $plannedS = 0; $unplannedS = 0; foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $c) { if ($c['category'] === 'planned') $plannedS = (int)$c['durata_s']; else $unplannedS += (int)$c['durata_s']; } $sqlDett = "SELECT p.id, p.Data, p.conferma_ordine, p.note_extra, l.name AS linea, m.nome AS matrice, c.nome AS cliente, p.tempo_totale_produzione AS occupato_s, p.seconds_pause AS pause_s, p.seconds_produzione AS netto_s, p.kgprod, p.mtprod, p.scarto, p.scarto_perc, p.id_status, (SELECT GROUP_CONCAT(mes.nome ORDER BY mes.nome SEPARATOR ', ') FROM productiondata_mescole pm JOIN mescole mes ON mes.id = pm.id_mescola WHERE pm.id_productiondata = p.id) AS mescole FROM productiondata p LEFT JOIN production_lines l ON l.id = p.id_linea LEFT JOIN matrice m ON m.id = p.idmatrice LEFT JOIN clients c ON c.id = p.id_cliente WHERE $whereSql ORDER BY p.Data DESC, p.id DESC LIMIT 500"; $stmt = $pdo->prepare($sqlDett); $stmt->execute($params); $dettaglio = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode([ 'success' => true, 'granularity' => $granul, 'kpi' => [ 'n_produzioni' => (int)$kpi['n_produzioni'], 'tot_occupato_s' => (int)$kpi['tot_occupato_s'], 'tot_pause_s' => (int)$kpi['tot_pause_s'], 'tot_netto_s' => (int)$kpi['tot_netto_s'], 'tot_kg' => (float)$kpi['tot_kg'], 'tot_mt' => (float)$kpi['tot_mt'], 'tot_scarto' => (float)$kpi['tot_scarto'], 'eff_tempo' => $effTempo, 'scarto_perc_tot' => $scartoPercTot, 'planned_s' => $plannedS, 'unplanned_s' => $unplannedS, 'saturazione' => $saturazione, 'giorni_range' => $giorniRange, ], 'per_linea' => $perLinea, 'serie' => $serie, 'dettaglio' => $dettaglio, ]); } catch (Exception $e) { echo json_encode(['success' => false, 'msg' => $e->getMessage()]); } exit; } ?>