getConnection(); $iduser = $iduserlogin ?? null; $rawInput = file_get_contents('php://input'); $input = json_decode($rawInput, true); if (!is_array($input)) { jsonResponse([ 'success' => false, 'message' => 'Payload JSON non valido.' ]); } $id = (int)($input['id'] ?? 0); if ($id <= 0) { jsonResponse([ 'success' => false, 'message' => 'ID non valido.' ]); } $areaMm2 = isset($input['area_mm2']) ? (float)$input['area_mm2'] : 0; $areaCm2 = isset($input['area_cm2']) ? (float)$input['area_cm2'] : 0; $outerAreaMm2 = isset($input['manual_outer_area_mm2']) ? (float)$input['manual_outer_area_mm2'] : $areaMm2; $holesAreaMm2 = isset($input['manual_holes_area_mm2']) ? (float)$input['manual_holes_area_mm2'] : 0; $widthMm = isset($input['width_mm']) ? (float)$input['width_mm'] : null; $heightMm = isset($input['height_mm']) ? (float)$input['height_mm'] : null; $calibrationPx = isset($input['manual_calibration_px']) ? (float)$input['manual_calibration_px'] : 0; $calibrationMm = isset($input['manual_calibration_mm']) ? (float)$input['manual_calibration_mm'] : 0; $mmPerPx = isset($input['manual_mm_per_px']) ? (float)$input['manual_mm_per_px'] : 0; $outerPolygon = $input['manual_polygon'] ?? null; $holes = $input['manual_holes'] ?? []; $roi = $input['roi'] ?? null; if ($areaMm2 <= 0) { jsonResponse([ 'success' => false, 'message' => 'Area finale non valida.' ]); } if ($outerAreaMm2 <= 0) { jsonResponse([ 'success' => false, 'message' => 'Area esterna non valida.' ]); } if ($holesAreaMm2 < 0) { jsonResponse([ 'success' => false, 'message' => 'Area fori non valida.' ]); } if ($calibrationPx <= 0 || $calibrationMm <= 0 || $mmPerPx <= 0) { jsonResponse([ 'success' => false, 'message' => 'Calibrazione non valida.' ]); } if (!is_array($outerPolygon) || count($outerPolygon) < 3) { jsonResponse([ 'success' => false, 'message' => 'Poligono esterno non valido. Servono almeno 3 punti.' ]); } if (!is_array($holes)) { $holes = []; } $manualPolygonJson = json_encode([ 'outer_polygon' => $outerPolygon, 'holes' => $holes, 'roi' => $roi, 'calibration' => $input['calibration'] ?? null, 'canvas' => $input['canvas'] ?? null, 'areas' => [ 'outer_area_mm2' => $outerAreaMm2, 'holes_area_mm2' => $holesAreaMm2, 'final_area_mm2' => $areaMm2, 'final_area_cm2' => $areaCm2 ] ]); $manualHolesJson = json_encode($holes); $roiX = null; $roiY = null; $roiW = null; $roiH = null; if (is_array($roi)) { $roiX = isset($roi['x']) ? (float)$roi['x'] : null; $roiY = isset($roi['y']) ? (float)$roi['y'] : null; $roiW = isset($roi['width']) ? (float)$roi['width'] : null; $roiH = isset($roi['height']) ? (float)$roi['height'] : null; } if ($iduser === null || $iduser === '') { $stmt = $pdo->prepare(" UPDATE cad_area_jobs SET roi_x = COALESCE(?, roi_x), roi_y = COALESCE(?, roi_y), roi_width = COALESCE(?, roi_width), roi_height = COALESCE(?, roi_height), roi_page = 1, status = 'completed', message = 'Area calcolata tramite tracciamento manuale calibrato.', area_mm2 = ?, area_cm2 = ?, area_m2 = ?, manual_area_mm2 = ?, manual_area_cm2 = ?, manual_outer_area_mm2 = ?, manual_holes_area_mm2 = ?, manual_width_mm = ?, manual_height_mm = ?, width_mm = ?, height_mm = ?, manual_calibration_px = ?, manual_calibration_mm = ?, manual_mm_per_px = ?, manual_polygon_json = ?, manual_holes_json = ?, manual_status = 'completed', scale_used = ?, scale_detected = ?, confidence = 'manual_validated', strategy_used = 'manual_tracing_with_exclusions', python_response = NULL, updated_at = NOW() WHERE id = ? "); $stmt->execute([ $roiX, $roiY, $roiW, $roiH, $areaMm2, $areaCm2, $areaMm2 / 1000000, $areaMm2, $areaCm2, $outerAreaMm2, $holesAreaMm2, $widthMm, $heightMm, $widthMm, $heightMm, $calibrationPx, $calibrationMm, $mmPerPx, $manualPolygonJson, $manualHolesJson, $mmPerPx, 'manual', $id ]); } else { $stmt = $pdo->prepare(" UPDATE cad_area_jobs SET roi_x = COALESCE(?, roi_x), roi_y = COALESCE(?, roi_y), roi_width = COALESCE(?, roi_width), roi_height = COALESCE(?, roi_height), roi_page = 1, status = 'completed', message = 'Area calcolata tramite tracciamento manuale calibrato.', area_mm2 = ?, area_cm2 = ?, area_m2 = ?, manual_area_mm2 = ?, manual_area_cm2 = ?, manual_outer_area_mm2 = ?, manual_holes_area_mm2 = ?, manual_width_mm = ?, manual_height_mm = ?, width_mm = ?, height_mm = ?, manual_calibration_px = ?, manual_calibration_mm = ?, manual_mm_per_px = ?, manual_polygon_json = ?, manual_holes_json = ?, manual_status = 'completed', scale_used = ?, scale_detected = ?, confidence = 'manual_validated', strategy_used = 'manual_tracing_with_exclusions', python_response = NULL, updated_at = NOW() WHERE id = ? AND iduser = ? "); $stmt->execute([ $roiX, $roiY, $roiW, $roiH, $areaMm2, $areaCm2, $areaMm2 / 1000000, $areaMm2, $areaCm2, $outerAreaMm2, $holesAreaMm2, $widthMm, $heightMm, $widthMm, $heightMm, $calibrationPx, $calibrationMm, $mmPerPx, $manualPolygonJson, $manualHolesJson, $mmPerPx, 'manual', $id, $iduser ]); } if ($stmt->rowCount() === 0) { jsonResponse([ 'success' => false, 'message' => 'Nessun record aggiornato. Controlla ID o utente.' ]); } jsonResponse([ 'success' => true, 'message' => 'Area manuale salvata correttamente.', 'area_mm2' => $areaMm2, 'area_cm2' => $areaCm2, 'outer_area_mm2' => $outerAreaMm2, 'holes_area_mm2' => $holesAreaMm2 ]); } catch (Throwable $e) { error_log('CAD manual area save error: ' . $e->getMessage()); jsonResponse([ 'success' => false, 'message' => $e->getMessage() ]); }