ikinci temizlik tamamlandı

This commit is contained in:
Ümit Tunç
2026-04-28 21:15:09 +03:00
parent f80443aec0
commit 37e7296527
8313 changed files with 2400677 additions and 0 deletions
View File
+32
View File
@@ -0,0 +1,32 @@
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue').default;
/**
* The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue
* components and automatically register them with their "basename".
*
* Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
*/
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app',
});
+32
View File
@@ -0,0 +1,32 @@
window._ = require('lodash');
try {
require('bootstrap');
} catch (e) {}
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
// import Echo from 'laravel-echo';
// window.Pusher = require('pusher-js');
// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: process.env.MIX_PUSHER_APP_KEY,
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
// forceTLS: true
// });
@@ -0,0 +1,23 @@
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
+7
View File
@@ -0,0 +1,7 @@
// Body
$body-bg: #f8fafc;
// Typography
$font-family-sans-serif: 'Nunito', sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;
+8
View File
@@ -0,0 +1,8 @@
// Fonts
@import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
@import 'variables';
// Bootstrap
@import '~bootstrap/scss/bootstrap';
@@ -0,0 +1,106 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
// Get selected tables from request
$selectedTables = request('tables', []);
if (empty($selectedTables)) {
echo json_encode([
'success' => false,
'message' => 'No tables selected'
]);
exit;
}
// Get all tables and their columns
$tables = Schema::getConnection()->getDoctrineSchemaManager()->listTableNames();
$dbStructure = [];
// Only include selected tables and their columns
foreach ($selectedTables as $table) {
if (in_array($table, $tables)) {
$columns = Schema::getColumnListing($table);
$columnTypes = [];
foreach ($columns as $column) {
$type = DB::connection()->getDoctrineColumn($table, $column)->getType()->getName();
$columnTypes[$column] = $type;
}
$dbStructure[$table] = $columnTypes;
}
}
// Get the prompt from the request
$prompt = request('prompt');
// Prepare the context for Gemini
$context = "Database Structure:\n";
foreach ($dbStructure as $table => $columns) {
$context .= "Table: $table\n";
foreach ($columns as $column => $type) {
$context .= " - $column ($type)\n";
}
$context .= "\n";
}
$context .= "\nUser Request: $prompt\n\n";
$context .= "Please generate a valid MySQL query that satisfies the user's request. Only return the SQL query without any explanations or markdown formatting.";
// Call Gemini API
$apiKey = setting('gemini_api_key');
$url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=" . $apiKey;
$data = [
"contents" => [
[
"parts" => [
["text" => $context]
]
]
],
"generationConfig" => [
"temperature" => 0.1,
"topK" => 1,
"topP" => 1,
"maxOutputTokens" => 2048,
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$result = json_decode($response, true);
if (isset($result['candidates'][0]['content']['parts'][0]['text'])) {
$sql = trim($result['candidates'][0]['content']['parts'][0]['text']);
// Remove any markdown code block formatting if present
$sql = preg_replace('/^```sql\s*|\s*```$/m', '', $sql);
echo json_encode([
'success' => true,
'sql' => $sql
]);
} else {
echo json_encode([
'success' => false,
'message' => 'Failed to generate SQL query'
]);
}
} else {
echo json_encode([
'success' => false,
'message' => 'Failed to communicate with Gemini API'
]);
}
?>
@@ -0,0 +1,213 @@
@php
/**
* Auto Translate - Google Translate Free API Integration
*
* Receives rows with empty 'ceviri' field and translates 'icerik' to target 'dil'
* Uses Google Translate unofficial free API endpoint
*
* POST Parameters:
* - rows: array of objects with {id, icerik, dil}
*
* Returns JSON:
* - success: boolean
* - translated: array of {id, ceviri}
* - errors: array of error messages
*/
header('Content-Type: application/json');
$rows = $request->input('rows', []);
if (empty($rows)) {
echo json_encode([
'success' => false,
'message' => 'No rows provided',
'translated' => [],
'errors' => []
]);
exit;
}
$translated = [];
$errors = [];
/**
* Convert snake_case or technical format to readable sentence
* Example: "paint_cycle" -> "Paint Cycle"
* Example: "protocol_date_cleaning" -> "Protocol Date Cleaning"
*
* @param string $text Input text (may contain underscores)
* @return string Formatted readable text
*/
function formatToReadable($text) {
// Replace underscores with spaces
$text = str_replace('_', ' ', $text);
// Replace multiple spaces with single space
$text = preg_replace('/\s+/', ' ', $text);
// Trim whitespace
$text = trim($text);
// Convert to title case (capitalize first letter of each word)
$text = ucwords(strtolower($text));
return $text;
}
/**
* Check if text looks like a technical/column name
* (contains underscores or is all lowercase with no spaces)
*
* @param string $text Text to check
* @return bool True if text appears to be technical format
*/
function isTechnicalFormat($text) {
// Contains underscore
if (strpos($text, '_') !== false) {
return true;
}
// All lowercase with no spaces (like "paintcycle")
if ($text === strtolower($text) && strpos($text, ' ') === false && strlen($text) > 3) {
return true;
}
return false;
}
/**
* Translate text using Google Translate Free API
*
* @param string $text Source text to translate
* @param string $targetLang Target language code (e.g., 'ru', 'tr')
* @param string $sourceLang Source language code (default: 'en')
* @return string|null Translated text or null on failure
*/
function googleTranslate($text, $targetLang, $sourceLang = 'en') {
if (empty($text) || empty($targetLang)) {
return null;
}
// Skip if source and target are the same
if ($sourceLang === $targetLang) {
return $text;
}
$url = 'https://translate.googleapis.com/translate_a/single';
$params = [
'client' => 'gtx',
'sl' => $sourceLang,
'tl' => $targetLang,
'dt' => 't',
'q' => $text
];
$fullUrl = $url . '?' . http_build_query($params);
// Use cURL for better control
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $fullUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Accept-Language: en-US,en;q=0.9'
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError || $httpCode !== 200) {
return null;
}
// Parse response - Google returns nested array structure
$data = json_decode($response, true);
if (!$data || !isset($data[0])) {
return null;
}
// Extract translated text from nested arrays
$translatedText = '';
foreach ($data[0] as $segment) {
if (isset($segment[0])) {
$translatedText .= $segment[0];
}
}
return $translatedText ?: null;
}
// Process each row
foreach ($rows as $row) {
$id = $row['id'] ?? null;
$icerik = $row['icerik'] ?? '';
$dil = $row['dil'] ?? '';
if (!$id) {
$errors[] = "Row missing ID";
continue;
}
if (empty($icerik)) {
$errors[] = "Row $id: Empty source text (icerik)";
continue;
}
if (empty($dil)) {
$errors[] = "Row $id: No target language specified";
continue;
}
// Format technical text (snake_case) to readable format before translation
$readableText = $icerik;
if (isTechnicalFormat($icerik)) {
$readableText = formatToReadable($icerik);
}
// Translate the formatted text
$translatedText = googleTranslate($readableText, $dil, 'en');
if ($translatedText === null) {
$errors[] = "Row $id: Translation failed for '$icerik' to '$dil'";
continue;
}
// Update the database
try {
db('translate')->where('id', $id)->update([
'ceviri' => $translatedText,
'updated_at' => now()
]);
$translated[] = [
'id' => $id,
'ceviri' => $translatedText
];
} catch (\Exception $e) {
$errors[] = "Row $id: Database update failed - " . $e->getMessage();
}
// Small delay to avoid rate limiting
usleep(100000); // 100ms delay between requests
}
echo json_encode([
'success' => count($translated) > 0,
'message' => count($translated) . ' rows translated successfully',
'translated' => $translated,
'errors' => $errors,
'total_requested' => count($rows),
'total_translated' => count($translated),
'total_errors' => count($errors)
]);
@endphp
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,83 @@
<?php
/**
* @api-readonly
* Cache blade views list - shows when each cache view was last updated
*/
use Illuminate\Support\Facades\Storage;
$cacheViewsList = [];
// Cache klasörünün varlığını kontrol et
$cacheDirectory = storage_path('documents/cache');
if (is_dir($cacheDirectory)) {
// Tüm _last_updated.txt dosyalarını bul
$files = glob($cacheDirectory . '/*_last_updated.txt');
foreach ($files as $file) {
$fileName = basename($file);
// Cache adını çıkar (_last_updated.txt kısmını kaldır)
$cacheName = str_replace('_last_updated.txt', '', $fileName);
// Dosya içeriğini oku (tarih bilgisi)
$lastUpdated = file_get_contents($file);
$lastUpdated = trim($lastUpdated);
// Dosya bilgilerini al
$fileModTime = filemtime($file);
// View path'i bul (cache dosyasından)
$cacheFile = $cacheDirectory . '/' . $cacheName . '.blade.php';
$cacheExists = file_exists($cacheFile);
$cacheFileSize = $cacheExists ? filesize($cacheFile) : 0;
// Ne kadar zaman önce güncellendiğini hesapla
$timeDiff = '';
if ($lastUpdated) {
try {
$updateTime = strtotime($lastUpdated);
$now = time();
$diffSeconds = $now - $updateTime;
if ($diffSeconds < 60) {
$timeDiff = $diffSeconds . ' saniye önce';
} elseif ($diffSeconds < 3600) {
$timeDiff = floor($diffSeconds / 60) . ' dakika önce';
} elseif ($diffSeconds < 86400) {
$timeDiff = floor($diffSeconds / 3600) . ' saat önce';
} else {
$timeDiff = floor($diffSeconds / 86400) . ' gün önce';
}
} catch (\Exception $e) {
$timeDiff = '-';
}
}
$cacheViewsList[] = [
'id' => count($cacheViewsList) + 1,
'cache_name' => $cacheName,
'last_updated' => $lastUpdated ?: '-',
'time_ago' => $timeDiff ?: '-',
'cache_file_exists' => $cacheExists,
'cache_file_size' => $cacheExists ? formatBytes($cacheFileSize) : '-',
'cache_file_size_bytes' => $cacheFileSize,
'file_mod_time' => date('Y-m-d H:i:s', $fileModTime)
];
}
// Son güncelleme tarihine göre sırala (en yeni en üstte)
usort($cacheViewsList, function($a, $b) {
return strtotime($b['last_updated']) - strtotime($a['last_updated']);
});
}
// Sonucu JSON olarak döndür
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'timestamp' => date('Y-m-d H:i:s'),
'total_count' => count($cacheViewsList),
'data' => $cacheViewsList
], JSON_PRETTY_PRINT);
?>
@@ -0,0 +1,477 @@
<?php
if (!defined('STAY_ALIVE')) {
header('Content-Type: application/json');
}
use Carbon\Carbon;
if (isset($_POST['paint']) || isset($_REQUEST['paint'])) {
$paint_release_number_pattern = setting("paint_release_number_pattern");
$checkNo = str_replace("{number}", get_counter($paint_release_number_pattern), $paint_release_number_pattern);
// Check if ISO+SPL pairs are provided (new format)
if (isset($_POST['iso_spool_pairs']) && !empty($_POST['iso_spool_pairs'])) {
$pairs = explode(",", $_POST['iso_spool_pairs']);
$count = 0;
foreach ($pairs as $pair) {
$pairParts = explode("|", trim($pair));
if (count($pairParts) == 2) {
$isoNumber = trim($pairParts[0]);
$spoolNumber = trim($pairParts[1]);
if (!empty($isoNumber) && !empty($spoolNumber)) {
$result = db("weld_logs")
->where("iso_number", $isoNumber)
->where("spool_number", $spoolNumber)
->whereNotIn("spool_status", ['Completed'])
->whereIn("spool_status", ['Paint', 'Spool Release', 'NDT Release', 'QC', 'Manufacturing'])
->update([
"spool_paint_check" => u() ? (u() ? u()->id : 0) : 0,
"paint_release_no" => $checkNo,
"paint_release_date" => simdi(),
"spool_status" => "Completed"
]);
$count += $result;
}
}
}
// Include paint follow-up updater
ob_start();
// echo view('admin.type.spool-release.paint-follow-up-updater')->render();
ob_end_clean();
// Dispatch cache blade views
dispatchCacheBladeViews();
echo json_encode([
'status' => 'success',
'message' => $count . ' row sign check affected',
'count' => $count
]);
if (defined('STAY_ALIVE'))
return;
exit();
}
// Fallback to old format for backward compatibility
elseif (isset($_POST['iso_number']) && !empty($_POST['iso_number'])) {
$spoolNumbers = explode(",", $_POST['spool_number']);
$isoNumbers = explode(",", $_POST['iso_number']);
$count = 0;
foreach ($isoNumbers as $isoNumber) {
$maxAttempts = 5;
$attempt = 0;
$result = db("weld_logs")
->where("iso_number", $isoNumber)
->where("spool_number", $spoolNumbers[$count])
->whereNotIn("spool_status", ['Completed'])
->whereIn("spool_status", ['Paint', 'Spool Release', 'NDT Release', 'QC', 'Manufacturing', 'Weld Complete'])
->update([
"spool_paint_check" => u() ? (u() ? u()->id : 0) : 0,
"paint_release_no" => $checkNo,
"paint_release_date" => simdi(),
"spool_status" => "Completed"
]);
$count++;
}
// Include paint follow-up updater
ob_start();
echo view('admin.type.spool-release.paint-follow-up-updater')->render();
ob_end_clean();
// Dispatch cache blade views
dispatchCacheBladeViews();
echo json_encode([
'status' => 'success',
'message' => $count . ' row sign check affected',
'count' => $count
]);
if (defined('STAY_ALIVE'))
return;
exit();
} else {
echo json_encode([
'status' => 'error',
'message' => 'ISO number is required in POST data'
]);
if (defined('STAY_ALIVE'))
return;
exit();
}
} else {
// Handle NDT Release
if (isset($_POST['ndt_release']) && !empty($_POST['ndt_release'])) {
$ndt_release_number_pattern = setting("ndt_release_number_pattern");
$newReleaseNo = str_replace("{number}", get_counter($ndt_release_number_pattern), $ndt_release_number_pattern);
// Check if ISO+SPL pairs are provided (new format)
if (isset($_POST['iso_spool_pairs']) && !empty($_POST['iso_spool_pairs'])) {
$pairs = explode(",", $_POST['iso_spool_pairs']);
$totalAffectedRows = 0;
foreach ($pairs as $pair) {
$pairParts = explode("|", trim($pair));
if (count($pairParts) == 2) {
$isoNumber = trim($pairParts[0]);
$spoolNumber = trim($pairParts[1]);
if (!empty($isoNumber) && !empty($spoolNumber)) {
$weldInfos = db("weld_logs");
$weldInfos = $weldInfos->where("iso_number", $isoNumber);
$weldInfos = $weldInfos->where("spool_number", $spoolNumber);
$weldInfos = $weldInfos->whereNotNull("spool_ndt_check_no");
$weldInfos = $weldInfos->whereNull("ndt_release_no");
$affectedRows = $weldInfos->update([
"ndt_release_no" => $newReleaseNo,
"ndt_release_check" => u() ? (u() ? u()->id : 0) : 0,
"ndt_release_date" => Carbon::now(),
'spool_status' => "Paint",
]);
$totalAffectedRows += $affectedRows;
}
}
}
// Dispatch cache blade views
dispatchCacheBladeViews();
echo json_encode([
'status' => 'success',
'message' => $totalAffectedRows . ' row affected',
'count' => $totalAffectedRows
]);
if (defined('STAY_ALIVE'))
return;
exit();
}
// Fallback to old format for backward compatibility
else {
$weldInfos = db("weld_logs");
// Apply filters from POST data
$get = $_POST;
unset($get['ndt_release'], $get['ndt_paint_release'], $get['page'], $get['rollback'], $get['_token'], $get['checklist-ok'], $get['iso_spool_pairs']);
foreach ($get as $col => $value) {
if ($col == "iso_number") {
$value = explode(",", $value);
}
if ($col == "spool_number") {
$value = explode(",", $value);
}
if ($value != "") {
if (is_array($value)) {
$weldInfos = $weldInfos->whereIn($col, $value);
} else {
$weldInfos = $weldInfos->where($col, trim($value));
}
}
}
$ndtReleaseUpdate = $weldInfos;
$ndtReleaseUpdate = $ndtReleaseUpdate->whereNotNull("spool_ndt_check_no");
$ndtReleaseUpdate = $ndtReleaseUpdate->whereNull("ndt_release_no");
$affectedRows = $ndtReleaseUpdate->update([
"ndt_release_no" => $newReleaseNo,
"ndt_release_check" => u() ? (u() ? u()->id : 0) : 0,
"ndt_release_date" => Carbon::now(),
'spool_status' => "Paint",
]);
// Dispatch cache blade views
dispatchCacheBladeViews();
echo json_encode([
'status' => 'success',
'message' => $affectedRows . ' row affected',
'count' => $affectedRows
]);
if (defined('STAY_ALIVE'))
return;
exit();
}
}
// Handle NDT & Paint Release
if (isset($_POST['ndt_paint_release']) && !empty($_POST['ndt_paint_release'])) {
$paint_release_number_pattern = setting("paint_release_number_pattern");
$totalAffectedRows = 0;
// Check if ISO+SPL pairs are provided (new format)
if (isset($_POST['iso_spool_pairs']) && !empty($_POST['iso_spool_pairs'])) {
$pairs = explode(",", $_POST['iso_spool_pairs']);
foreach ($pairs as $pair) {
$pairParts = explode("|", trim($pair));
if (count($pairParts) == 2) {
$isoNumber = trim($pairParts[0]);
$spoolNumber = trim($pairParts[1]);
if (!empty($isoNumber) && !empty($spoolNumber)) {
$newRequestNo = $paint_release_number_pattern;
$newRequestNo = str_replace("{number}", get_counter($newRequestNo), $newRequestNo);
$whereData = [
'iso_number' => $isoNumber,
'spool_number' => $spoolNumber
];
$checkPaintingCycle = db("weld_logs")
->where($whereData)
->select("painting_cycle")
->first();
$spoolStatus = (!empty($checkPaintingCycle) && !empty($checkPaintingCycle->painting_cycle)) ? "Paint" : "Completed";
$updateData = [
"ndt_release_no" => $newRequestNo,
"ndt_release_check" => u() ? (u() ? u()->id : 0) : 0,
"ndt_release_date" => Carbon::now(),
'spool_status' => $spoolStatus,
];
$ndtReleaseUpdate = db("weld_logs");
$ndtReleaseUpdate = $ndtReleaseUpdate->where($whereData);
$ndtReleaseUpdate = $ndtReleaseUpdate->whereNotNull("spool_ndt_check_no");
$ndtReleaseUpdate = $ndtReleaseUpdate->whereNull("ndt_release_date");
$affectedRows = $ndtReleaseUpdate->update($updateData);
$totalAffectedRows += $affectedRows;
// Include paint follow-up updater (capture ALL output to prevent HTML output)
if ($affectedRows > 0) {
try {
// Start output buffering to capture any HTML output (including from bilgi() function)
// Use multiple levels to ensure we catch everything
ob_start();
ob_start();
// Render the view - this will execute bilgi() and capture its output
$rendered = view('admin.type.spool-release.paint-follow-up-updater')->render();
// Clean all output buffers
ob_end_clean();
ob_end_clean();
} catch (\Exception $e) {
// Silently catch any errors and clean all output buffers
while (ob_get_level() > 0) {
ob_end_clean();
}
}
}
}
}
}
}
// Fallback to old format for backward compatibility
elseif (isset($_POST['iso_number']) && !empty($_POST['iso_number'])) {
$isoNumbers = explode(",", $_POST['iso_number']);
$spoolNumbers = [];
if (isset($_POST['spool_number']) && !empty($_POST['spool_number'])) {
$spoolNumbers = explode(",", $_POST['spool_number']);
}
// Calculate total updates - if spool_numbers exist, use min, otherwise use iso_numbers count
$totalUpdates = count($isoNumbers);
if (count($spoolNumbers) > 0) {
$totalUpdates = min(count($isoNumbers), count($spoolNumbers));
}
for ($i = 0; $i < $totalUpdates; $i++) {
$newRequestNo = $paint_release_number_pattern;
$newRequestNo = str_replace("{number}", get_counter($newRequestNo), $newRequestNo);
$whereData = [
'iso_number' => trim($isoNumbers[$i]),
];
if (isset($spoolNumbers[$i]) && !empty($spoolNumbers[$i])) {
$whereData['spool_number'] = trim($spoolNumbers[$i]);
}
$checkPaintingCycle = db("weld_logs")
->where($whereData)
->select("painting_cycle")
->first();
$spoolStatus = (!empty($checkPaintingCycle) && !empty($checkPaintingCycle->painting_cycle)) ? "Paint" : "Completed";
$updateData = [
"ndt_release_no" => $newRequestNo,
"ndt_release_check" => u() ? (u() ? u()->id : 0) : 0,
"ndt_release_date" => Carbon::now(),
'spool_status' => $spoolStatus,
];
$ndtReleaseUpdate = db("weld_logs");
$ndtReleaseUpdate = $ndtReleaseUpdate->where($whereData);
$ndtReleaseUpdate = $ndtReleaseUpdate->whereNotNull("spool_ndt_check_no");
$ndtReleaseUpdate = $ndtReleaseUpdate->whereNull("ndt_release_date");
$affectedRows = $ndtReleaseUpdate->update($updateData);
$totalAffectedRows += $affectedRows;
// Include paint follow-up updater (capture ALL output to prevent HTML output)
if ($affectedRows > 0) {
try {
$isoNumber = trim($isoNumbers[$i]);
// Start output buffering to capture any HTML output (including from bilgi() function)
// Use multiple levels to ensure we catch everything
ob_start();
ob_start();
// Render the view - this will execute bilgi() and capture its output
$rendered = view('admin.type.spool-release.paint-follow-up-updater')->render();
// Clean all output buffers
ob_end_clean();
ob_end_clean();
} catch (\Exception $e) {
// Silently catch any errors and clean all output buffers
while (ob_get_level() > 0) {
ob_end_clean();
}
}
}
}
}
// Dispatch cache blade views
dispatchCacheBladeViews();
echo json_encode([
'status' => 'success',
'message' => $totalAffectedRows . ' row affected',
'count' => $totalAffectedRows
]);
if (defined('STAY_ALIVE'))
return;
exit();
}
// Handle Checklist OK (existing functionality)
$spool_release_check_number_pattern = setting("spool_release_check_number_pattern");
$checkNo = str_replace("{number}", get_counter($spool_release_check_number_pattern), $spool_release_check_number_pattern);
if (isset($_POST['checklist-ok'])) {
// Check if ISO+SPL pairs are provided (new format)
if (isset($_POST['iso_spool_pairs']) && !empty($_POST['iso_spool_pairs'])) {
$pairs = explode(",", $_POST['iso_spool_pairs']);
$totalAffectedRows = 0;
foreach ($pairs as $pair) {
$pairParts = explode("|", trim($pair));
if (count($pairParts) == 2) {
$isoNumber = trim($pairParts[0]);
$spoolNumber = trim($pairParts[1]);
if (!empty($isoNumber) && !empty($spoolNumber)) {
$result = db("weld_logs")
->where("iso_number", $isoNumber)
->where("spool_number", $spoolNumber)
->whereIn("spool_status", ["Spool Release", "Manufacturing", "Weld Complete"])
->update([
"spool_ndt_check" => u() ? (u() ? u()->id : 0) : 0,
"spool_ndt_check_no" => $checkNo,
"spool_ndt_check_date" => simdi(),
"spool_status" => "NDT Release"
]);
$totalAffectedRows += $result;
}
}
}
// Include spool document generate
ob_start();
echo view('admin.type.spool-release.spool-document-generate')->render();
ob_end_clean();
// Include spool status changer
ob_start();
echo view('cron.spool-status-changer', [
'iso_spool_pairs' => $_POST['iso_spool_pairs']
])->render();
ob_end_clean();
// Dispatch cache blade views
dispatchCacheBladeViews();
echo json_encode([
'status' => 'success',
'message' => $totalAffectedRows . ' row sign check',
'count' => $totalAffectedRows
]);
if (defined('STAY_ALIVE'))
return;
exit();
}
// Fallback to old format for backward compatibility
elseif (isset($_POST['iso_number']) && !empty($_POST['iso_number'])) {
$isoNumbers = explode(",", $_POST['iso_number']);
$spoolNumbers = explode(",", $_POST['spool_number']);
$totalUpdates = min(count($isoNumbers), count($spoolNumbers));
$totalAffectedRows = 0;
for ($i = 0; $i < $totalUpdates; $i++) {
$currentIso = trim($isoNumbers[$i]);
$currentSpool = trim($spoolNumbers[$i]);
$result = db("weld_logs")
->where("iso_number", $currentIso)
->where("spool_number", $currentSpool)
->whereIn("spool_status", ["Spool Release", "Manufacturing", "Weld Complete"])
->update([
"spool_ndt_check" => u() ? (u() ? u()->id : 0) : 0,
"spool_ndt_check_no" => $checkNo,
"spool_ndt_check_date" => simdi(),
"spool_status" => "NDT Release"
]);
$totalAffectedRows += $result;
}
// Include spool document generate
ob_start();
echo view('admin.type.spool-release.spool-document-generate')->render();
ob_end_clean();
// Include spool status changer
ob_start();
echo view('cron.spool-status-changer', [
'iso_number' => $_POST['iso_number'],
'spool_number' => $_POST['spool_number']
])->render();
ob_end_clean();
// Dispatch cache blade views
dispatchCacheBladeViews();
echo json_encode([
'status' => 'success',
'message' => $totalAffectedRows . ' row sign check',
'count' => $totalAffectedRows
]);
if (defined('STAY_ALIVE'))
return;
exit();
} else {
echo json_encode([
'status' => 'error',
'message' => 'ISO number is required in POST data'
]);
exit();
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'No valid action specified'
]);
if (defined('STAY_ALIVE'))
return;
exit();
}
}
?>
@@ -0,0 +1,31 @@
<?php
use Illuminate\Support\Facades\Cache;
try {
// Tüm cron report builder setting'lerini default değerlere döndür
$documentTemplates = DB::table("document_templates")->where("y", "1")->get();
foreach ($documentTemplates as $template) {
$cacheKey = "cron_report_builder_template_{$template->id}";
$progressCacheKey = "cron_report_builder_progress_{$template->id}";
// Setting'leri default değerlere döndür
setting_put($cacheKey, "0"); // Template index'ini 0'a döndür
setting_put($progressCacheKey, '{"processed_count":0,"error_count":0,"success_count":0,"total_records":0}'); // Progress'i sıfırla
}
// Genel progress setting'ini de default değere döndür
setting_put('cron_report_builder_overall_progress', '{"last_run":"Never","execution_time":0,"status":"not_started"}');
echo json_encode([
'success' => true,
'message' => 'All cron settings reset to default values successfully'
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => 'Failed to reset settings: ' . $e->getMessage()
]);
}
?>
@@ -0,0 +1,45 @@
<?php
$column = [];
$column['name'] = post("name");
$column['type'] = post("type");
$column['relation'] = []; //json_decode(post("relation"));
$relationDatas = [];
$relationDatas[$column['name']] = [];//$column['relation'];
$rowName = "click-edit";
$tableName = post("table_name");
$unique = post("id") . post("name");
$listData = db($tableName)->where("id", post("id"))->first();
?>
<div class="editable-zone" id="{{$unique}}">
@include("components.columns.{$column['type']}")
</div>
<script>
$("#{{$unique}} input").on("blur", function() {
var that = $(this);
var value = that.val();
$.post("{{ url('admin-ajax/input-edit') }}",{
table : that.attr("table"),
key : that.attr("key"),
value : that.val(),
_token : "{{ csrf_token() }}",
id : that.attr("data-id"),
name : that.attr("name")
},function(){
that.prop("disabled",false);
that.parent().parent().html(value).removeClass("edited");
that.prop("disabled",true);
});
});
</script>
@@ -0,0 +1,8 @@
<?php
// Clone row functionality - redirects to AdminController
$table = post("table");
// Redirect to AdminController cloneRow method
$controller = new \App\Http\Controllers\AdminController();
$controller->cloneRow(request(), $table);
?>
@@ -0,0 +1,363 @@
<?php
/**
* @api-readonly
* Returns column history comments
*/
use App\Models\ColumnComment;
use App\Models\User;
use Carbon\Carbon;
use Carbon\CarbonInterval;
$id = get("id");
$table = get("table");
$columnName = get("column");
// Get comments from our new table
$users = User::all();
$comments = ColumnComment::where('table_name', $table)
->where('record_id', $id)
->where('column_name', $columnName)
->orderBy('created_at', 'DESC')
->get();
$weldLogEditInfo = null;
$weldLogInfoMessages = [];
$showWeldLogTimer = ($table === 'weld_logs' && $columnName === 'welding_date');
if ($showWeldLogTimer) {
$latestWeldingDateComment = $comments->first(function ($comment) {
return stripos($comment->comment ?? '', 'welding date set') !== false;
});
$limitHours = (float) setting('weld_log_edit_time_limit');
$exceptLevelsRaw = setting('weld_log_edit_time_limit_except_levels');
$exceptLevels = $exceptLevelsRaw ? j($exceptLevelsRaw) : [];
if (!is_array($exceptLevels)) {
$exceptLevels = [];
}
$currentUserLevel = optional(u())->level;
$isExcept = $currentUserLevel && in_array($currentUserLevel, $exceptLevels);
if ($isExcept) {
$weldLogInfoMessages[] = "Your level is excluded from the weld log edit time limit.";
}
if ($latestWeldingDateComment && $limitHours > 0) {
$commentTime = Carbon::parse($latestWeldingDateComment->created_at);
$expiresAt = $commentTime->copy()->addHours($limitHours);
$now = Carbon::now();
$totalSeconds = (int) ($limitHours * 3600);
$secondsLeft = $now->diffInSeconds($expiresAt, false);
$isEditable = $secondsLeft > 0;
$secondsLeft = max(0, $secondsLeft);
$elapsedSeconds = max(0, $totalSeconds - $secondsLeft);
$percent = $totalSeconds > 0 ? round(($elapsedSeconds / $totalSeconds) * 100, 1) : 100;
$interval = CarbonInterval::seconds($secondsLeft)->cascade();
$weldLogEditInfo = [
'isEditable' => $isEditable,
'secondsLeft' => $secondsLeft,
'humanLeft' => $isEditable ? $interval->forHumans(['short' => true, 'parts' => 2]) : '0 minutes',
'limitHours' => $limitHours,
'percent' => min(100, max(0, $percent)),
'expiresAt' => $expiresAt,
'commentTime' => $commentTime,
'exceptLevels' => $exceptLevels,
];
} elseif ($limitHours > 0) {
$weldLogInfoMessages[] = "No recent welding date change was found to calculate the countdown.";
}
}
// Convert comments to JSON for DataGrid
$commentsJson = json_encode($comments);
// Convert users to a lookup object for DataGrid
$usersLookup = [];
foreach ($users as $user) {
$usersLookup[$user->id] = $user->name;
}
$usersJson = json_encode($usersLookup);
if($comments->count() > 0 || true)
{
?>
<?php if ($showWeldLogTimer): ?>
<div class="alert alert-info">
<?php if ($weldLogEditInfo): ?>
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-between">
<div>
<div><strong>Status:</strong> <?php echo $weldLogEditInfo['isEditable'] ? 'Currently editable' : 'Currently not editable'; ?></div>
<div><strong>Remaining Time:</strong> <?php echo $weldLogEditInfo['isEditable'] ? $weldLogEditInfo['humanLeft'] : 'Expired'; ?> (limit: <?php echo $weldLogEditInfo['limitHours']; ?> hours)</div>
<div><strong>Expires At:</strong> <?php echo $weldLogEditInfo['expiresAt']->format('d.m.Y H:i'); ?></div>
<?php if (!empty($weldLogEditInfo['exceptLevels'])): ?>
<div><small>Except Levels: <?php echo implode(', ', $weldLogEditInfo['exceptLevels']); ?></small></div>
<?php endif; ?>
</div>
<div class="flex-grow-1 w-100 w-md-auto mt-3 mt-md-0">
<div class="progress" style="height: 20px;">
<div
class="progress-bar <?php echo $weldLogEditInfo['isEditable'] ? 'bg-success' : 'bg-danger'; ?>"
role="progressbar"
style="width: <?php echo $weldLogEditInfo['percent']; ?>%;"
aria-valuenow="<?php echo $weldLogEditInfo['percent']; ?>"
aria-valuemin="0"
aria-valuemax="100">
<?php echo $weldLogEditInfo['percent']; ?>%
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php
if (!$weldLogEditInfo && empty($weldLogInfoMessages)) {
$weldLogInfoMessages[] = 'Weld log edit time limit is not configured.';
}
?>
<?php if (!empty($weldLogInfoMessages)): ?>
<div class="mt-3">
<?php foreach ($weldLogInfoMessages as $infoMessage): ?>
<div><strong>Info:</strong> <?php echo $infoMessage; ?></div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="card mb-3">
<div class="card-header">
<h5>
<span class="badge badge-primary">{{e2($table)}}</span> /
<span class="badge badge-secondary">{{e2($id)}}</span> /
<span class="badge badge-success">{{e2($columnName)}}</span>
<span class="badge badge-default">{{e2("Add Comment")}}</span>
</h5>
</div>
<div class="card-body">
<form id="columnCommentForm" method="post">
@csrf
<input type="hidden" name="table_name" value="<?php echo $table; ?>">
<input type="hidden" name="record_id" value="<?php echo $id; ?>">
<input type="hidden" name="column_name" value="<?php echo $columnName; ?>">
<input type="hidden" name="column_value" value="">
<div class="form-group">
<label for="comment">{{e2("Your Comment")}}</label>
<textarea class="form-control" id="comment" name="comment" rows="3" required></textarea>
</div>
<button type="submit" class="btn btn-primary">{{e2("Submit Comment")}}</button>
</form>
</div>
</div>
<div class="card fullsize-grid">
<div class="card-header">
<h5>{{e2("Comments History")}}</h5>
</div>
<div class="card-body p-0">
<!-- DevExtreme DataGrid container -->
<div id="commentsDataGrid" style="width: 100%;"></div>
</div>
</div>
<?php
} else {
?>
<div class="alert alert-info">{{e2("No Comments Found")}}</div>
<?php
}
// Add JS for form submission
?>
<style>
/* DataGrid için stil ayarları */
.dx-datagrid {
min-height: 500px;
}
/* Card gövdesi padding kaldırma */
.card-body.p-0 {
padding: 0 !important;
}
/* Card kendisi için margin ayarları */
.card.fullsize-grid {
margin-bottom: 0 !important;
}
</style>
<script>
$(function() {
// Format date for DataGrid
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
}
// Users lookup table from server
const usersLookup = <?php echo $usersJson; ?>;
// Format user information
function formatUser(userId) {
return usersLookup[userId] || 'Unknown';
}
// Calculate grid height - responsive approach
function calculateGridHeight() {
// Minimum yükseklik 500px, aksi takdirde pencere yüksekliğinin %70'i
return Math.max(500, window.innerHeight * 0.7);
}
// Initialize DataGrid with comments data
const comments = <?php echo $commentsJson; ?>;
const dataGrid = $("#commentsDataGrid").dxDataGrid({
dataSource: comments,
showBorders: true,
height: calculateGridHeight(),
width: "100%",
filterRow: {
visible: true,
applyFilter: "auto"
},
searchPanel: {
visible: true,
width: 240,
placeholder: "Search..."
},
headerFilter: {
visible: true
},
grouping: {
autoExpandAll: false
},
paging: {
pageSize: 10
},
pager: {
showPageSizeSelector: true,
allowedPageSizes: [5, 10, 20, 50],
showInfo: true
},
columnAutoWidth: true,
columns: [
{
dataField: "created_at",
caption: "Date",
dataType: "datetime",
format: "dd.MM.yyyy HH:mm",
sortOrder: "desc",
width: 160
},
{
dataField: "comment",
caption: "Comment",
dataType: "string",
width: 350
},
{
dataField: "column_value",
caption: "Value at Comment Time",
dataType: "string",
width: 200
},
{
dataField: "user_id",
caption: "User",
lookup: {
dataSource: Object.entries(usersLookup).map(([id, name]) => ({ id: parseInt(id), name: name })),
displayExpr: "name",
valueExpr: "id"
},
width: 150
},
{
dataField: "ip_address",
caption: "IP Address",
dataType: "string",
width: 120
}
],
export: {
enabled: true,
allowExportSelectedData: true
},
onContentReady: function(e) {
if(comments.length === 0) {
e.component.option("noDataText", "No comments found");
}
}
}).dxDataGrid("instance");
// Pencere yeniden boyutlandırıldığında grid yüksekliğini güncelle
$(window).on("resize", function() {
dataGrid.option("height", calculateGridHeight());
});
// Form submission handler
$('#columnCommentForm').submit(function(e) {
e.preventDefault();
$.ajax({
url: '<?php echo url('api/column-comment'); ?>',
type: 'POST',
data: $(this).serialize(),
success: function(response) {
if(response.success) {
// Show success message with SweetAlert
Swal.fire({
icon: 'success',
title: 'Success!',
text: 'Your comment has been added successfully.',
confirmButtonText: 'OK'
}).then((result) => {
// After alert is closed, refresh the content
refreshComments();
});
// Clear the form
$('#comment').val('');
} else {
Swal.fire({
icon: 'error',
title: 'Error!',
text: response.message || 'Failed to add comment.',
confirmButtonText: 'OK'
});
}
},
error: function(xhr) {
Swal.fire({
icon: 'error',
title: 'Error!',
text: 'An error occurred while processing your request.',
confirmButtonText: 'OK'
});
}
});
});
// Function to refresh comments
function refreshComments() {
$.ajax({
url: '<?php echo url('admin-ajax/column-history?column=' . $columnName . '&id=' . $id . '&table=' . $table); ?>',
type: 'GET',
success: function(data) {
// Use a simple approach: replace the entire container contents
const currentContainer = $('#commentsDataGrid').closest('.card').parent();
currentContainer.html(data);
},
error: function() {
console.error('Failed to refresh comments');
}
});
}
// Modal size adjustment if needed
if ($("#modal-popin").length) {
$("#modal-popin .modal-dialog").addClass("modal-lg");
}
});
</script>
@@ -0,0 +1,167 @@
<?php
use Barryvdh\DomPDF\Facade\Pdf;
use Carbon\Carbon;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
set_time_limit(-1);
ini_set('max_execution_time', -1);
setlocale(LC_ALL, 'ru_RU.utf8');
App::setLocale("ru");
try {
$startTime = microtime(true);
$data = j($_POST['data']);
$documentInfo = document_template("Construction_Paint_Log");
$j = j($documentInfo->json);
// Get counter values for report numbers
$reportNoCounter = get_counter("Construction_Paint_Log");
$constructionReportNoCounter = get_counter("Construction_Report");
// Get patterns from settings
$reportNoPattern = setting('construction_paint_log_pattern');
$constructionReportNoPattern = setting('construction_report_pattern');
// Generate report numbers
$reportNo = str_replace("{number}", $reportNoCounter, $reportNoPattern);
$constructionReportNo = str_replace("{number}", $constructionReportNoCounter, $constructionReportNoPattern);
// Update report numbers in the database
foreach($data as $item) {
$updateData = [
"report_no" => $reportNo,
"construction_report_no" => $constructionReportNo,
'updated_at' => now()
];
db("construction_paint_logs")
->where("id", $item['id'])
->update($updateData);
}
// Load Excel template
$spreadsheet = IOFactory::load('storage/documents/' . $documentInfo->files);
$sheet = $spreadsheet->getActiveSheet();
$templateRowNo = 16;
$startRow = $templateRowNo;
// Get template row cells and formulas
$templateRowCells = [];
$templateFormulas = [];
foreach ($sheet->getRowIterator($startRow)->current()->getCellIterator() as $cell) {
$templateRowCells[] = $cell->getValue();
if ($cell->isFormula()) {
$colIndex = $cell->getColumn();
$templateFormulas[$colIndex] = $cell->getValue();
}
}
// Get merged cells in template row
$mergedCells = [];
foreach ($sheet->getMergeCells() as $mergeRange) {
if (preg_match('/^\D*'.$startRow.'$/', explode(':', $mergeRange)[0])) {
$mergedCells[] = $mergeRange;
}
}
// Process each selected record
foreach($data as $index => $item) {
// Get full record data
$record = db("construction_paint_logs")->where("id", $item['id'])->first();
// Insert new row
$sheet->insertNewRowBefore($startRow + 1, 1);
$newRow = $sheet->getRowIterator($startRow + 1)->current();
// Copy template values and replace placeholders
$cellIndex = 0;
foreach ($newRow->getCellIterator() as $newCell) {
$newCellValue = $templateRowCells[$cellIndex];
$colLetter = $newCell->getColumn();
if (isset($templateFormulas[$colLetter])) {
// Handle formulas
$formula = $templateFormulas[$colLetter];
$rowOffset = $index + 1;
// Update formula references
$updatedFormula = preg_replace_callback(
'/([A-Z]+)(\d+)/',
function($matches) use ($rowOffset) {
$col = $matches[1];
$row = intval($matches[2]);
return $col . ($row + $rowOffset);
},
$formula
);
$newCell->setValue($updatedFormula);
} else {
// Replace placeholders with actual values
foreach((array)$record as $field => $value) {
if (is_string($value)) {
$newCellValue = str_replace('{'.$field.'}', $value, $newCellValue);
}
}
$newCell->setValue($newCellValue);
}
$cellIndex++;
}
// Apply merged cells to new row
foreach ($mergedCells as $mergeRange) {
$adjustedMergeRange = preg_replace_callback(
'/\d+/',
function($matches) use ($startRow) {
return $matches[0] + 1;
},
$mergeRange
);
$sheet->mergeCells($adjustedMergeRange);
}
$startRow++;
}
// Remove template row
$sheet->removeRow(intval($templateRowNo));
// Save Excel file
$fileName = $reportNo . '.xlsx';
$documentPath = $documentInfo->kid;
$path = "storage/documents/$documentPath/$fileName";
if (!file_exists(dirname($path))) {
mkdir(dirname($path), 0777, true);
}
try {
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save($path);
} catch (\Exception $e) {
Log::error('Error saving Excel file', [
'error' => $e->getMessage(),
'file_path' => $path
]);
throw $e;
}
// Convert to PDF
$pdfResult = xlsx_to_pdf_legacy($path, "storage/documents/$documentPath");
echo $pdfResult;
$endTime = microtime(true);
} catch (\Exception $e) {
Log::error('Fatal error in PDF generation process', [
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
throw $e;
}
?>
@@ -0,0 +1,32 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$p = $request->all();
$id = $p['id'];
if(getisset("table")) {
ekle2([
'title' => "",
"slug" => rand()
],get("table"));
request()->back();
} else {
$c = Contents::where("slug",$id)->first();
$content = new Contents;
$content->title = "";
$content->tkid = json_encode(Contents::getTree($id));
$content->breadcrumb = Contents::getBreadcrumbs($id,"{title} / ");
$content->slug = rand(1111111,99999999);
$content->type = $p['type'];
$content->kid = $id;
$content->save();
$return = redirect("admin/new/contents");
echo $return;
}
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$c2 = c($_GET['cid']);
if($c2) {
$c = new Contents;
$c->title = $c2->title;
$c->kid = $c2->kid;
$c->breadcrumb = $c2->breadcrumb;
@@ -0,0 +1,113 @@
<?php
namespace App\Http\Controllers;
use App;
use Illuminate\Http\Request;
use App\Contents;
use App\Types;
use App\Fields;
use Illuminate\Support\Facades\DB;
$c = c(get("cid"));
$types = Types::get();
$fields = Fields::get();
?>
<form action="{{url('admin-ajax/content-update?back')}}" id="edit-form" method="post">
{{csrf_field()}}
<div class="row">data-id="{{$c->id}}" class="form-control edit"
<div class="col-md-12">
{{__('Başlık')}}
<input type="hidden" name="id" value="{{$c->id}}" />
<input type="hidden" name="kid" value="{{$c->kid}}" />
<input type="hidden" name="oldslug" value="{{$c->slug}}" />
<input type="text" name="title" id="title" value="{{$c->title}}" class="form-control" />
{{__('URL')}} <div class="btn btn-default" onclick="$.get('{{url('admin-ajax/slug?title='.$c->breadcrumb)}}'+$('#title').val(),function(d){
$('#slug').val(d)
})"><i class="si si-refresh"></i></div>
<input type="text" name="slug" id="slug" value="{{$c->slug}}" class="form-control" />
{{__('İçerik Tipi')}}
<select name="type"data-id="{{$c->id}}" class="form-control edit" table="contents" >
<option value="">Tip Seçiniz</option>
@foreach(@$types AS $t)
<option value="{{$t->title}}" @if($t->title==$c->type) selected @endif>{{$t->title}}</option>
@endforeach
</select>
{{__('İçerik')}}
<textarea id="editor" name="html">{{$c->html}}</textarea>
<script type="text/javascript">
CKEDITOR.replace( 'editor', {
language: '{{App::getLocale()}}',
removePlugins: 'image',
extraPlugins: 'base64image'
});
</script>
<?php sf("#edit-form"); ?>
</div>
</div>
<hr />
<div class="">
<button class="btn btn-primary">{{__('Değişiklikleri Kaydet')}}</button>
</div>
</form>
@@ -0,0 +1,31 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$p = $request->all();
if(isset($p['contents'])) {
$id = $p['kid'];
print_R($p['contents']);
print_R($p['type']);
$breadcrumb = Contents::getBreadcrumbs($id,"{title} / ");
$tree = Contents::getTree($id);
$c = Contents::where("slug",$id)->first();
foreach($p['contents'] AS $title) {
@@ -0,0 +1,16 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$data = ( json_decode($_POST['data']));
foreach($data AS $d) {
@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
if(getisset("table")) {
ekle2([
'title' => "",
'kid' => "main",
"slug" => rand()
],get("table"));
} else {
$p = $request->all();
$content = new Contents;
$content->title = "";
$content->slug = rand(1111111,99999999);
$content->type = $p['type'];
$content->kid = "main";
$content->s = 0;
$content->save();
}
$return = back();
echo $return;
@@ -0,0 +1,14 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$p = $request->all();
DB::table("contents")
->where('id', $p['id'])
->update([
"title" => $p['title'],
"kid" => $p['kid'],
"slug" => $p['slug'],
"type" => $p['type'],
"html" => $p['html'],
@@ -0,0 +1,97 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$p = $request->all();
$bu = Contents::where("slug",$p['id'])->first();
$contents = Contents::where("kid",$p['id'])
->where("title","<>",'')
->select("title","kid","slug","id")
->get();
?>
<?php if($contents->count()!=0) { ?>
<?php
// echo "<ul>";
foreach($contents AS $c) {
if($c->title!="") {
?>
<li>
<label for="menu-<?php echo($c->id) ?>" onclick="location.href='{{url("admin/contents/".$c->id)}}'" ><?php e2($c->title) ?></label>
<input type="checkbox" slug="<?php e2($c->slug); ?>" class="kategori-tree" id="menu-<?php echo($c->id) ?>" />
<ol>
</ol>
</li>
<?php
}
}
// echo "</ul>";
?>
</li>
<?php } ?>
<script type="text/javascript">
$(function(){
$(".kategori-tree").on("click",function(){
console.log("ok");
var bu = $(this);
bu.parent().children("ol").html("{{__('Bekleyiniz...')}}");
$.get('{{url('admin-ajax/contents-tree?id=')}}'+$(this).attr("slug"),function(d){
bu.parent().children("ol").html(d);
});
//return false;
});
});
</script>
<?php
$return = null;
?>
@@ -0,0 +1,7 @@
import pandas as pd
# XLSX dosyasını oku
df = pd.read_excel('storage/documents/Excel%20Form%20Templates/rfi.xlsx')
# HTML dosyasına yaz
df.to_html('storage/documents/Excel%20Form%20Templates/rfi.html', index=False)
@@ -0,0 +1,11 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$post = $request->all();
@@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$post = $request->all();
$ext = $request->cover->getClientOriginalExtension();
$path = $request->cover->storeAs('files/'.date("Y")."/".date("m"),$request['slug']."-".date("his").'.'.$ext);
@@ -0,0 +1,20 @@
<?php
$zipPath = "storage/documents/zip_files/";
@mkdir($zipPath, 0777, true);
if(getisset("path")){
$pdfDirectory = get("path");
}
$zipName = str_replace("storage/documents/", "", $pdfDirectory);
$zipName = str_replace("/", "", $zipName);
$zip_file = "$zipPath/$zipName.zip";
$command = "zip -r -j '$zip_file' '$pdfDirectory' ";
dump($command);
echo shell_exec($command);
//shell_exec("rm -r '$pdfDirectory' ")
?>
<a href="{{url($zip_file)}}" class="btn btn-primary">{{e2("Download PDF Zip File")}}</a>
@@ -0,0 +1,20 @@
<?php
$zipPath = "storage/documents/013_Others/zip_files/";
@mkdir($zipPath, 0777, true);
if(getisset("path")){
$pdfDirectory = get("path");
$pdfDirectory = "storage/documents/$pdfDirectory";
}
//$zipName = str_replace("storage/documents/", "", $pdfDirectory);
$zipName = get("name");
$zip_file = "$zipPath/$zipName.zip";
$command = "zip -r -j '$zip_file' '$pdfDirectory' ";
dump(shell_exec($command));
//shell_exec("rm -r '$pdfDirectory' ")
?>
<a href="{{url($zip_file)}}" class="btn btn-primary">{{e2("Download Zip File")}}</a>
@@ -0,0 +1,48 @@
<?php
/**
* @api-readonly
* Returns crew performance statistics
*/
$year = isset($_GET['year']) ? (int)$_GET['year'] : date('Y');
// Get crew performance data by month
$crewQuery = db("weld_logs")
->select([
"ste_subcontractor",
"mechanic_supervisor",
DB::raw('MONTH(mechanic_supervisor_control_date) as month'),
DB::raw('ROUND(SUM(nps_1), 2) as nps1'),
DB::raw('COUNT(*) as joint_count')
])
->whereYear("mechanic_supervisor_control_date", $year)
->whereNotNull("mechanic_supervisor")
->whereNotNull("mechanic_supervisor_control_date")
->groupBy("ste_subcontractor", "mechanic_supervisor", DB::raw('MONTH(mechanic_supervisor_control_date)'))
->orderBy("ste_subcontractor")
->orderBy("mechanic_supervisor")
->get();
// Restructure data for DataGrid
$crewData = [];
foreach($crewQuery as $row) {
$key = $row->ste_subcontractor . '|' . $row->mechanic_supervisor;
if(!isset($crewData[$key])) {
$crewData[$key] = [
'ste_subcontractor' => $row->ste_subcontractor,
'mechanic_supervisor' => $row->mechanic_supervisor,
];
// Initialize all 12 months
for($i = 1; $i <= 12; $i++) {
$crewData[$key]['month_' . $i . '_nps1'] = 0;
$crewData[$key]['month_' . $i . '_count'] = 0;
}
}
// Set month data
$crewData[$key]['month_' . $row->month . '_nps1'] = $row->nps1;
$crewData[$key]['month_' . $row->month . '_count'] = $row->joint_count;
}
echo json_encode_tr(array_values($crewData));
?>
@@ -0,0 +1,41 @@
<?php
// Genel ilerleme bilgisini al
$overallProgressJson = setting('cron_report_builder_overall_progress', false, '{"last_run":"Never","execution_time":0,"status":"not_started"}');
$overallProgress = json_decode($overallProgressJson, true);
// Aktif template'lerin durumunu al
$documentTemplates = DB::table("document_templates")->where("y", "1")->get();
$templateStatuses = [];
foreach ($documentTemplates as $template) {
$cacheKey = "cron_report_builder_template_{$template->id}";
$progressCacheKey = "cron_report_builder_progress_{$template->id}";
$lastProcessedIndex = (int)setting($cacheKey, false, "0");
$progressJson = setting($progressCacheKey, false, '{"processed_count":0,"error_count":0,"success_count":0,"total_records":0}');
$progress = json_decode($progressJson, true);
// Template'in tamamlanıp tamamlanmadığını kontrol et
$isCompleted = setting($cacheKey) === "0" && $progress['processed_count'] > 0;
$templateStatuses[] = [
'id' => $template->id,
'name' => $template->name ?? $template->title ?? 'N/A',
'last_processed_index' => $lastProcessedIndex,
'processed_count' => $progress['processed_count'],
'error_count' => $progress['error_count'],
'success_count' => $progress['success_count'],
'total_records' => $progress['total_records'],
'is_completed' => $isCompleted,
'progress_percentage' => $progress['total_records'] > 0 ? round(($progress['processed_count'] / $progress['total_records']) * 100, 2) : 0
];
}
// JSON response döndür
echo json_encode([
'overall_progress' => $overallProgress,
'template_statuses' => $templateStatuses,
'timestamp' => now()->toISOString()
]);
?>
@@ -0,0 +1,30 @@
<?php
$u = u();
if($u->level=="Admin")
{
$directory = 'storage/documents/008_Test_Pack/001_TP Preperation_Documents';
if (is_dir($directory)) {
$files = glob($directory . '/*'); // Tüm dosyaları al
foreach ($files as $file) {
if (is_file($file)) {
unlink($file); // Dosyayı sil
} else if (is_dir($file)) {
// Klasörü silmeden önce içindeki tüm dosyaları ve alt klasörleri sil
$filesInDir = glob($file . '/*'); // Klasördeki tüm dosyaları ve alt klasörleri al
foreach ($filesInDir as $subFile) {
if (is_file($subFile)) {
unlink($subFile); // Dosyayı sil
} else if (is_dir($subFile)) {
rmdir($subFile); // Boş klasörü sil
}
}
rmdir($file); // Klasörü sil
}
}
bilgi("All files $directory in have been deleted.");
} else {
bilgi("Directory does not exist.");
}
}
?>
@@ -0,0 +1,40 @@
<?php
use Illuminate\Support\Facades\Storage;
// CSRF token kontrolü
if (!isset($_POST['_token']) || !csrf_token()) {
echo json_encode(['status' => 'error', 'message' => 'CSRF token error']);
exit();
}
try {
$logsPath = storage_path('logs');
$deletedCount = 0;
// Tüm log dosyalarını tara
$logFiles = glob($logsPath . '/*.log');
foreach ($logFiles as $logFile) {
$fileName = basename($logFile);
// Sadece .log uzantılı dosyaları sil
if (pathinfo($fileName, PATHINFO_EXTENSION) === 'log') {
if (unlink($logFile)) {
$deletedCount++;
}
}
}
echo json_encode([
'status' => 'success',
'message' => $deletedCount . ' log files have been successfully deleted',
'deleted_count' => $deletedCount
]);
} catch (Exception $e) {
echo json_encode([
'status' => 'error',
'message' => 'An error occurred while deleting log files: ' . $e->getMessage()
]);
}
?>
@@ -0,0 +1,26 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use File;
use Illuminate\Support\Facades\DB;
$post = $request->all();
/*
$ext = $request->file->getClientOriginalExtension();
$path = $request->file->storeAs("files/{$post['slug']}",$post['slug']."-".$post['id']."-".rand(111,999).'.'.$ext);
$path = str_replace("files/","",$path);
*/
@@ -0,0 +1,9 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
@@ -0,0 +1,42 @@
<?php
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;
// CSRF token kontrolü
if (!isset($_POST['_token']) || !csrf_token()) {
echo json_encode(['status' => 'error', 'message' => 'CSRF token error']);
exit();
}
try {
// Bugünün tarihini al
$today = Carbon::today()->format('Y-m-d');
$logsPath = storage_path('logs');
$deletedCount = 0;
// Tüm log dosyalarını tara
$logFiles = glob($logsPath . '/*.log');
foreach ($logFiles as $logFile) {
$fileName = basename($logFile);
// Laravel log dosya formatı: laravel-YYYY-MM-DD.log
if (preg_match('/truncgil-' . $today . '\.log$/', $fileName)) {
if (unlink($logFile)) {
$deletedCount++;
}
}
}
echo json_encode([
'status' => 'success',
'message' => $deletedCount . ' log files have been successfully deleted',
'deleted_count' => $deletedCount
]);
} catch (Exception $e) {
echo json_encode([
'status' => 'error',
'message' => 'An error occurred while deleting log files: ' . $e->getMessage()
]);
}
?>
+7
View File
@@ -0,0 +1,7 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
@@ -0,0 +1,302 @@
@php
/**
* @api-readonly
* Returns developer project statistics from GitHub
*/
use Illuminate\Support\Facades\Http;
use Carbon\Carbon;
// Configuration
$token = env('GITHUB_TOKEN');
$org = 'Truncgil-Techology';
$projectNumber = 2;
if (!$token) {
echo json_encode(['status' => 'error', 'message' => 'GITHUB_TOKEN not set']);
exit;
}
// GraphQL Query to fetch Project V2 items and fields
$query = <<<GRAPHQL
query {
organization(login: "$org") {
projectV2(number: $projectNumber) {
title
items(first: 100) {
nodes {
fieldValues(first: 20) {
nodes {
... on ProjectV2ItemFieldSingleSelectValue {
name
field {
... on ProjectV2FieldCommon {
name
}
}
}
... on ProjectV2ItemFieldUserValue {
users(first: 5) {
nodes {
login
avatarUrl
name
}
}
field {
... on ProjectV2FieldCommon {
name
}
}
}
}
}
content {
... on Issue {
title
url
state
number
createdAt
updatedAt
closedAt
}
... on DraftIssue {
title
createdAt
updatedAt
}
... on PullRequest {
title
url
state
number
createdAt
updatedAt
closedAt
}
}
}
}
}
}
}
GRAPHQL;
try {
$response = Http::withToken($token)->post('https://api.github.com/graphql', [
'query' => $query
]);
if ($response->failed()) {
throw new Exception("GitHub API Error: " . $response->body());
}
$data = $response->json();
if (isset($data['errors'])) {
throw new Exception("GraphQL Error: " . json_encode($data['errors']));
}
$project = $data['data']['organization']['projectV2'] ?? null;
if (!$project) {
throw new Exception("Project not found or access denied.");
}
$items = $project['items']['nodes'];
// Data structures for advanced analysis
$developerStats = [];
$timelineStats = [
'weekly' => [],
'monthly' => []
];
$detailedItems = []; // Array for DataGrid
$statusMapping = [
'Done' => 'completed',
'Ready' => 'active',
'In progress' => 'active',
'In review' => 'active',
'Backlog' => 'pending',
'No Status' => 'pending'
];
foreach ($items as $item) {
$status = 'No Status';
$size = 'No Size';
$assignees = [];
// Parse Field Values
foreach ($item['fieldValues']['nodes'] as $fieldValue) {
if (!isset($fieldValue['field']['name'])) continue;
$fieldName = $fieldValue['field']['name'];
if ($fieldName === 'Status') {
$status = $fieldValue['name'];
} elseif ($fieldName === 'Size') {
$size = $fieldValue['name'];
} elseif ($fieldName === 'Assignees') {
foreach ($fieldValue['users']['nodes'] as $user) {
$assignees[] = $user['login'];
}
}
}
if (empty($assignees)) {
$assignees[] = 'Unassigned';
}
// Content details
$content = $item['content'] ?? [];
$title = $content['title'] ?? 'Untitled';
$url = $content['url'] ?? '#';
$state = $content['state'] ?? 'OPEN';
$createdAt = $content['createdAt'] ?? null;
$updatedAt = $content['updatedAt'] ?? null;
$closedAt = $content['closedAt'] ?? null;
// Determine completion date
$completionDate = ($state === 'CLOSED' || $state === 'MERGED' || $status === 'Done')
? ($closedAt ?? $updatedAt)
: null;
$isCompleted = ($completionDate !== null);
// Duration Calculation
$duration = 'N/A';
$durationSeconds = 0;
if ($createdAt) {
try {
$cStart = Carbon::parse($createdAt);
$endDateStr = $isCompleted ? $completionDate : $updatedAt;
if (!$endDateStr) $endDateStr = $createdAt;
$cEnd = Carbon::parse($endDateStr);
$diff = $cStart->diff($cEnd);
$parts = [];
if ($diff->y > 0) $parts[] = $diff->y . 'y';
if ($diff->m > 0) $parts[] = $diff->m . 'mo';
if ($diff->d > 0) $parts[] = $diff->d . 'd';
if ($diff->h > 0) $parts[] = $diff->h . 'h';
if (empty($parts) && $diff->i > 0) $parts[] = $diff->i . 'm';
if (empty($parts)) $parts[] = '0m';
$duration = implode(' ', array_slice($parts, 0, 2));
$durationSeconds = $cStart->diffInSeconds($cEnd);
} catch (Exception $e) {
$duration = 'Error';
}
}
// Add to detailed items list (For DataGrid)
$detailedItems[] = [
'title' => $title,
'status' => $status,
'size' => $size,
'assignees' => implode(', ', $assignees),
'url' => $url,
'duration' => $duration,
'duration_seconds' => $durationSeconds,
'created_at' => $createdAt ? Carbon::parse($createdAt)->format('Y-m-d H:i') : '-',
'end_date' => $completionDate ? Carbon::parse($completionDate)->format('Y-m-d H:i') : '-'
];
// Analyze for each assignee (For Charts/Cards)
foreach ($assignees as $assignee) {
if (!isset($developerStats[$assignee])) {
$developerStats[$assignee] = [
'total_tasks' => 0,
'completed_tasks' => 0,
'active_tasks' => 0,
'pending_tasks' => 0,
'sizes' => [],
'completion_history' => []
];
}
$developerStats[$assignee]['total_tasks']++;
$generalStatus = $statusMapping[$status] ?? 'active';
if ($isCompleted) {
$developerStats[$assignee]['completed_tasks']++;
if ($completionDate) {
$cDate = Carbon::parse($completionDate);
$monthKey = $cDate->format('Y-m');
if (!isset($developerStats[$assignee]['completion_history']['monthly'][$monthKey])) {
$developerStats[$assignee]['completion_history']['monthly'][$monthKey] = 0;
}
$developerStats[$assignee]['completion_history']['monthly'][$monthKey]++;
}
} else {
if ($generalStatus === 'active') {
$developerStats[$assignee]['active_tasks']++;
} else {
$developerStats[$assignee]['pending_tasks']++;
}
}
if (!isset($developerStats[$assignee]['sizes'][$size])) {
$developerStats[$assignee]['sizes'][$size] = 0;
}
$developerStats[$assignee]['sizes'][$size]++;
}
}
// Format Developer Stats for Frontend
$performanceData = [];
foreach ($developerStats as $assignee => $stats) {
$performanceData[] = [
'assignee' => $assignee,
'total' => $stats['total_tasks'],
'completed' => $stats['completed_tasks'],
'active' => $stats['active_tasks'],
'pending' => $stats['pending_tasks'],
'completion_rate' => $stats['total_tasks'] > 0 ? round(($stats['completed_tasks'] / $stats['total_tasks']) * 100, 1) : 0,
'sizes' => $stats['sizes'],
'history' => $stats['completion_history']
];
}
// Format Timeline Data
$timelineChartData = [];
$allMonths = [];
foreach ($developerStats as $assignee => $stats) {
if (isset($stats['completion_history']['monthly'])) {
$allMonths = array_merge($allMonths, array_keys($stats['completion_history']['monthly']));
}
}
$allMonths = array_unique($allMonths);
sort($allMonths);
foreach ($allMonths as $month) {
$row = ['month' => $month];
foreach ($developerStats as $assignee => $stats) {
$row[$assignee] = $stats['completion_history']['monthly'][$month] ?? 0;
}
$timelineChartData[] = $row;
}
echo json_encode([
'status' => 'success',
'project_title' => $project['title'],
'developer_performance' => $performanceData,
'timeline_chart' => $timelineChartData,
'raw_items' => $detailedItems, // Restored this field for DataGrid
'meta' => [
'total_tasks' => count($items)
]
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
echo json_encode(['status' => 'error', 'message' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
@endphp
@@ -0,0 +1,198 @@
@php
/**
* @api-readonly
* Returns developer team statistics from GitHub
*/
use Illuminate\Support\Facades\Http;
use Carbon\Carbon;
// Configuration
$token = env('GITHUB_TOKEN');
$repoStr = env('GITHUB_REPO'); // Expected format: "owner/repo"
// Filter Configuration:
// Commits with total line changes (additions + deletions) greater than this value
// will have their line counts ignored in the stats (treated as 0 lines).
// This effectively bypasses vendor/node_modules dumps or massive removals.
$ignoredLinesThreshold = 5000;
if (!$token || !$repoStr) {
echo json_encode([
'status' => 'error',
'message' => 'GITHUB_TOKEN or GITHUB_REPO not set in .env'
]);
exit;
}
$parts = explode('/', $repoStr);
if (count($parts) !== 2) {
echo json_encode(['status' => 'error', 'message' => 'Invalid GITHUB_REPO format. Expected owner/repo']);
exit;
}
$owner = $parts[0];
$name = $parts[1];
// GraphQL Query to fetch Commits
// This allows us to see authors even if they are not verified GitHub users (unlike stats/contributors)
$query = <<<GRAPHQL
query(\$owner: String!, \$name: String!, \$cursor: String) {
repository(owner: \$owner, name: \$name) {
defaultBranchRef {
target {
... on Commit {
history(first: 25, after: \$cursor) {
pageInfo {
hasNextPage
endCursor
}
nodes {
committedDate
additions
deletions
author {
name
email
user {
login
avatarUrl
}
}
}
}
}
}
}
}
}
GRAPHQL;
try {
$allCommits = [];
$cursor = null;
$hasNextPage = true;
$pageCount = 0;
$maxPages = 20; // Fetch up to 1000 commits to avoid timeout
while ($hasNextPage && $pageCount < $maxPages) {
$response = Http::withToken($token)
->withHeaders([
'User-Agent' => 'Laravel/10.0',
'Accept' => 'application/json',
])
->post('https://api.github.com/graphql', [
'query' => $query,
'variables' => [
'owner' => $owner,
'name' => $name,
'cursor' => $cursor
]
]);
if ($response->failed()) {
throw new Exception("GitHub API Error: " . $response->body());
}
$json = $response->json();
if (isset($json['errors'])) {
throw new Exception("GraphQL Error: " . json_encode($json['errors']));
}
$history = $json['data']['repository']['defaultBranchRef']['target']['history'] ?? null;
if (!$history) {
break;
}
$commits = $history['nodes'];
$allCommits = array_merge($allCommits, $commits);
$hasNextPage = $history['pageInfo']['hasNextPage'];
$cursor = $history['pageInfo']['endCursor'];
$pageCount++;
}
// Process Data
$monthlyStats = [];
$monthlyTotals = [];
$totalCommitsProject = 0;
foreach ($allCommits as $commit) {
// Outlier Filter (Bypass Vendor/Large Changes)
// If a commit changes more lines than the threshold, we ignore its line counts
// but still count it as a commit activity.
$totalChanges = $commit['additions'] + $commit['deletions'];
if ($totalChanges > $ignoredLinesThreshold) {
$commit['additions'] = 0;
$commit['deletions'] = 0;
}
$date = Carbon::parse($commit['committedDate']);
$monthKey = $date->format('Y-m');
$authorData = $commit['author'];
// Prefer GitHub Login, fallback to Git Author Name
$authorName = $authorData['user']['login'] ?? $authorData['name'] ?? 'Unknown';
// Grouping key
$key = $authorName . '_' . $monthKey;
// Initialize Monthly Total for relative percentage
if (!isset($monthlyTotals[$monthKey])) {
$monthlyTotals[$monthKey] = 0;
}
$monthlyTotals[$monthKey]++;
// Initialize Developer Stats
if (!isset($monthlyStats[$key])) {
$monthlyStats[$key] = [
'author' => $authorName,
'month' => $monthKey,
'added' => 0,
'deleted' => 0,
'commits' => 0,
];
}
$monthlyStats[$key]['added'] += $commit['additions'];
$monthlyStats[$key]['deleted'] += $commit['deletions'];
$monthlyStats[$key]['commits']++;
$totalCommitsProject++;
}
// Calculate percentages and format for DevExtreme
$resultData = array_values($monthlyStats);
// Sort by month descending
usort($resultData, function($a, $b) {
return strcmp($b['month'], $a['month']);
});
// Add percentages
foreach ($resultData as &$item) {
// Global contribution percentage
$item['percentage'] = $totalCommitsProject > 0 ? round(($item['commits'] / $totalCommitsProject) * 100, 2) : 0;
// Monthly relative contribution percentage
$monthTotal = $monthlyTotals[$item['month']] ?? 0;
$item['monthly_percentage'] = $monthTotal > 0 ? round(($item['commits'] / $monthTotal) * 100, 2) : 0;
}
echo json_encode([
'status' => 'success',
'data' => $resultData,
'meta' => [
'repo' => $repoStr,
'total_commits' => $totalCommitsProject,
'fetched_commits' => count($allCommits),
'ignored_threshold' => $ignoredLinesThreshold
]
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
echo json_encode([
'status' => 'error',
'message' => $e->getMessage()
], JSON_UNESCAPED_UNICODE);
}
@endphp
@@ -0,0 +1,18 @@
<?php
$row = j(get("row"));
$id = null;
if(isset($row['id'])) $id = $row['id'];
$query = db("r_f_i_s")
->where("discipline", $row['discipline'])
->where("id","!=", $id)
->where("rfi_no", $row['rfi_no'])
->orderBy("id", "DESC")->count();
if($query>0) {
echo 0;
} else {
echo 1;
}
?>
@@ -0,0 +1,356 @@
@php
/**
* @api-readonly
* System disk usage information
*/
use Illuminate\Support\Facades\Cache;
$result = Cache::remember('system_disk_usage_stats', 3600, function() {
// Disk kullanım durumunu topla
$diskInfo = [];
$directorySizes = [];
// Ana disk bilgilerini al
$diskUsage = shell_exec('df -h / 2>/dev/null | tail -n 1');
$diskParts = preg_split('/\s+/', trim($diskUsage));
$diskInfo = [
'filesystem' => $diskParts[0] ?? 'Unknown',
'total_size' => $diskParts[1] ?? '0',
'used' => $diskParts[2] ?? '0',
'available' => $diskParts[3] ?? '0',
'use_percentage' => str_replace('%', '', $diskParts[4] ?? '0'),
'mount_point' => $diskParts[5] ?? '/'
];
// Ana dizinlerin boyutlarını al
$directories = [
'/var' => 'var',
'/usr' => 'usr',
'/root' => 'root',
'/opt' => 'opt',
'/tmp' => 'tmp',
'/boot' => 'boot',
'/etc' => 'etc'
];
foreach($directories as $path => $name) {
$size = shell_exec("du -sh $path 2>/dev/null | cut -f1");
if($size) {
$directorySizes[] = [
'directory' => $name,
'path' => $path,
'size_text' => trim($size),
'size_bytes' => convertToBytes(trim($size))
];
}
}
// /var alt dizinlerini al
$varSubDirs = [
'/var/lib' => 'var/lib (Database)',
'/var/www' => 'var/www (Web Files)',
'/var/log' => 'var/log (Log Files)',
'/var/cache' => 'var/cache (Cache)'
];
$varDetails = [];
foreach($varSubDirs as $path => $name) {
$size = shell_exec("du -sh $path 2>/dev/null | cut -f1");
if($size) {
$varDetails[] = [
'directory' => $name,
'path' => $path,
'size_text' => trim($size),
'size_bytes' => convertToBytes(trim($size))
];
}
}
// Web projeleri detayları
$webProjects = [];
$webPath = '/var/www/html';
if(is_dir($webPath)) {
$projects = glob($webPath . '/*', GLOB_ONLYDIR);
foreach($projects as $project) {
$projectName = basename($project);
$size = shell_exec("du -sh '$project' 2>/dev/null | cut -f1");
if($size) {
$webProjects[] = [
'project' => $projectName,
'path' => $project,
'size_text' => trim($size),
'size_bytes' => convertToBytes(trim($size))
];
}
}
// Boyuta göre sırala
usort($webProjects, function($a, $b) {
return $b['size_bytes'] - $a['size_bytes'];
});
}
// Log dosyaları detayları
$logFiles = [];
$logPath = '/var/log';
if(is_dir($logPath)) {
$logs = shell_exec("du -sh $logPath/* 2>/dev/null | sort -hr | head -10");
if($logs) {
$logLines = explode("\n", trim($logs));
foreach($logLines as $line) {
if(trim($line)) {
$parts = preg_split('/\s+/', trim($line), 2);
if(count($parts) >= 2) {
$logFiles[] = [
'file' => basename($parts[1]),
'path' => $parts[1],
'size_text' => $parts[0],
'size_bytes' => convertToBytes($parts[0])
];
}
}
}
}
}
// Bellek bilgilerini al
$memInfo = shell_exec('free -h | grep Mem');
$memParts = preg_split('/\s+/', trim($memInfo));
$memoryInfo = [
'total' => $memParts[1] ?? '0',
'used' => $memParts[2] ?? '0',
'free' => $memParts[3] ?? '0',
'shared' => $memParts[4] ?? '0',
'buff_cache' => $memParts[5] ?? '0',
'available' => $memParts[6] ?? '0'
];
// Chart için veri hazırla
$chartData = [];
foreach($directorySizes as $dir) {
if($dir['size_bytes'] > 1000000) { // 1MB'dan büyük olanları göster
$chartData[] = [
'directory' => $dir['directory'],
'size' => round($dir['size_bytes'] / (1024*1024*1024), 2), // GB cinsinden
'percentage' => round(($dir['size_bytes'] / convertToBytes($diskInfo['total_size'])) * 100, 1)
];
}
}
// /var dizini detaylı analizi
$varDetailedAnalysis = [];
// MySQL veritabanları detayı
$mysqlSize = shell_exec("du -sh /var/lib/mysql 2>/dev/null | cut -f1");
if($mysqlSize) {
$varDetailedAnalysis[] = [
'component' => 'MySQL Databases',
'path' => '/var/lib/mysql',
'size_text' => trim($mysqlSize),
'size_bytes' => convertToBytes(trim($mysqlSize)),
'description' => 'Veritabanı dosyaları'
];
}
// Web projeleri detayı
$webSize = shell_exec("du -sh /var/www 2>/dev/null | cut -f1");
if($webSize) {
$varDetailedAnalysis[] = [
'component' => 'Web Projects',
'path' => '/var/www',
'size_text' => trim($webSize),
'size_bytes' => convertToBytes(trim($webSize)),
'description' => 'Web sitesi dosyaları'
];
}
// Log dosyaları
$logSize = shell_exec("du -sh /var/log 2>/dev/null | cut -f1");
if($logSize) {
$varDetailedAnalysis[] = [
'component' => 'System Logs',
'path' => '/var/log',
'size_text' => trim($logSize),
'size_bytes' => convertToBytes(trim($logSize)),
'description' => 'Sistem günlük dosyaları'
];
}
// Cache dosyaları
$cacheSize = shell_exec("du -sh /var/cache 2>/dev/null | cut -f1");
if($cacheSize) {
$varDetailedAnalysis[] = [
'component' => 'Cache Files',
'path' => '/var/cache',
'size_text' => trim($cacheSize),
'size_bytes' => convertToBytes(trim($cacheSize)),
'description' => 'Önbellek dosyaları'
];
}
// /var/lib altında mysql dışındaki dosyalar
$libOthersSize = shell_exec("du -sh /var/lib 2>/dev/null | cut -f1");
$libOthersBytes = 0;
if($libOthersSize && $mysqlSize) {
$libTotalBytes = convertToBytes(trim($libOthersSize));
$mysqlBytes = convertToBytes(trim($mysqlSize));
$libOthersBytes = $libTotalBytes - $mysqlBytes;
if($libOthersBytes > 1000000) { // 1MB'dan büyükse ekle
$varDetailedAnalysis[] = [
'component' => 'Other System Data',
'path' => '/var/lib (others)',
'size_text' => formatBytes($libOthersBytes),
'size_bytes' => $libOthersBytes,
'description' => 'Sistem paketleri ve diğer veriler'
];
}
}
// /var altında diğer klasörler
$varOthers = shell_exec("du -sh /var/* 2>/dev/null | grep -v '/var/lib\|/var/www\|/var/log\|/var/cache' | sort -hr");
if($varOthers) {
$otherLines = explode("\n", trim($varOthers));
$othersTotalBytes = 0;
foreach($otherLines as $line) {
if(trim($line)) {
$parts = preg_split('/\s+/', trim($line), 2);
if(count($parts) >= 2) {
$othersTotalBytes += convertToBytes($parts[0]);
}
}
}
if($othersTotalBytes > 1000000) { // 1MB'dan büyükse ekle
$varDetailedAnalysis[] = [
'component' => 'Other Directories',
'path' => '/var (others)',
'size_text' => formatBytes($othersTotalBytes),
'size_bytes' => $othersTotalBytes,
'description' => 'Diğer sistem klasörleri'
];
}
}
// Web Projects Chart Data (sadece /var/www projeleri)
$webProjectsChartData = [];
foreach($webProjects as $project) {
$webProjectsChartData[] = [
'project' => $project['project'],
'size' => round($project['size_bytes'] / (1024*1024*1024), 2), // GB cinsinden
'percentage' => round(($project['size_bytes'] / convertToBytes(trim($webSize))) * 100, 1),
'description' => 'Web Project'
];
}
// System Components Chart Data (MySQL, Logs, Cache, vs.)
$systemComponentsData = [];
// MySQL
if($mysqlSize) {
$systemComponentsData[] = [
'component' => 'MySQL Databases',
'size' => round(convertToBytes(trim($mysqlSize)) / (1024*1024*1024), 2),
'percentage' => round((convertToBytes(trim($mysqlSize)) / convertToBytes('332G')) * 100, 1),
'description' => 'Veritabanı dosyaları',
'color' => '#ff6b6b'
];
}
// System Logs
if($logSize) {
$systemComponentsData[] = [
'component' => 'System Logs',
'size' => round(convertToBytes(trim($logSize)) / (1024*1024*1024), 2),
'percentage' => round((convertToBytes(trim($logSize)) / convertToBytes('332G')) * 100, 1),
'description' => 'Sistem günlük dosyaları',
'color' => '#4ecdc4'
];
}
// Cache Files
if($cacheSize) {
$systemComponentsData[] = [
'component' => 'Cache Files',
'size' => round(convertToBytes(trim($cacheSize)) / (1024*1024*1024), 2),
'percentage' => round((convertToBytes(trim($cacheSize)) / convertToBytes('332G')) * 100, 1),
'description' => 'Önbellek dosyaları',
'color' => '#45b7d1'
];
}
// Other System Data (var/lib içinde mysql dışı + diğer var klasörleri)
$otherSystemBytes = 0;
// /var/lib içinde mysql dışı
if($libOthersSize && $mysqlSize) {
$libTotalBytes = convertToBytes(trim($libOthersSize));
$mysqlBytes = convertToBytes(trim($mysqlSize));
$libOthersBytes = $libTotalBytes - $mysqlBytes;
$otherSystemBytes += $libOthersBytes;
}
// /var altında diğer klasörler (lib, www, log, cache dışı)
$varOthers = shell_exec("du -sh /var/* 2>/dev/null | grep -v '/var/lib\|/var/www\|/var/log\|/var/cache' | sort -hr");
if($varOthers) {
$otherLines = explode("\n", trim($varOthers));
foreach($otherLines as $line) {
if(trim($line)) {
$parts = preg_split('/\s+/', trim($line), 2);
if(count($parts) >= 2) {
$otherSystemBytes += convertToBytes($parts[0]);
}
}
}
}
if($otherSystemBytes > 1000000) { // 1MB'dan büyükse ekle
$systemComponentsData[] = [
'component' => 'Other System Data',
'size' => round($otherSystemBytes / (1024*1024*1024), 2),
'percentage' => round(($otherSystemBytes / convertToBytes('332G')) * 100, 1),
'description' => 'Sistem paketleri ve diğer klasörler',
'color' => '#96ceb4'
];
}
return [
'success' => true,
'timestamp' => date('Y-m-d H:i:s'),
'disk_info' => $diskInfo,
'directory_sizes' => $directorySizes,
'var_details' => $varDetails,
'var_detailed_analysis' => $varDetailedAnalysis,
'web_projects' => $webProjects,
'log_files' => $logFiles,
'memory_info' => $memoryInfo,
'chart_data' => $chartData,
'web_projects_chart_data' => $webProjectsChartData,
'system_components_chart_data' => $systemComponentsData
];
});
// Bytes'ı human readable'a çeviren fonksiyon
function convertToBytes($size) {
$size = trim($size);
$unit = strtoupper(substr($size, -1));
$value = floatval($size);
switch($unit) {
case 'K': return $value * 1024;
case 'M': return $value * 1024 * 1024;
case 'G': return $value * 1024 * 1024 * 1024;
case 'T': return $value * 1024 * 1024 * 1024 * 1024;
default: return $value;
}
}
// formatBytes() fonksiyonu zaten sistemde mevcut, kullanacağız
// Sonucu JSON olarak döndür
header('Content-Type: application/json');
echo json_encode($result, JSON_PRETTY_PRINT);
@endphp
@@ -0,0 +1,293 @@
<?php
$folderPath = request('folder_path');
$storagePath = storage_path("documents/$folderPath");
$files = [];
if (is_dir($storagePath)) {
$items = scandir($storagePath);
foreach ($items as $item) {
if ($item != '.' && $item != '..') {
$fullPath = $storagePath . '/' . $item;
$relativePath = 'documents/' . $folderPath . '/' . $item;
if (is_file($fullPath)) {
$extension = strtolower(pathinfo($item, PATHINFO_EXTENSION));
$fileType = '';
$icon = '';
if (in_array($extension, ['xlsx', 'xls'])) {
$fileType = 'Excel';
$icon = 'fa-file-excel';
} elseif ($extension == 'pdf') {
$fileType = 'PDF';
$icon = 'fa-file-pdf';
} else {
$fileType = 'Other';
$icon = 'fa-file';
}
$fileSize = file_exists($fullPath) ? filesize($fullPath) : 0;
$files[] = [
'id' => count($files) + 1,
'name' => $item,
'type' => $fileType,
'extension' => $extension,
'size' => $fileSize,
'modified' => date('Y-m-d H:i:s', filemtime($fullPath)),
'path' => $relativePath,
'full_path' => $fullPath
];
}
}
}
}
// Dosyaları tarihe göre sırala (en yeni önce)
usort($files, function($a, $b) {
return strtotime($b['modified']) - strtotime($a['modified']);
});
?>
<style>
.file-grid-container {
margin-bottom: 20px;
}
.pdf-viewer-container {
margin-top: 20px;
border: 1px solid #ddd;
border-radius: 5px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.pdf-viewer-container iframe {
width: 100%;
height: 600px;
border: none;
}
.pdf-viewer-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 10px 15px;
display: flex;
justify-content: space-between;
align-items: center;
}
.pdf-viewer-header h6 {
margin: 0;
font-weight: 600;
}
.pdf-viewer-close {
background: none;
border: none;
color: white;
font-size: 1.2em;
cursor: pointer;
padding: 0;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: background 0.2s;
}
.pdf-viewer-close:hover {
background: rgba(255,255,255,0.2);
}
.file-action-btn {
margin-right: 5px;
margin-bottom: 5px;
transition: all 0.2s;
}
.file-action-btn:hover {
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.no-files-message {
text-align: center;
padding: 40px;
color: #666;
}
@media (max-width: 768px) {
.pdf-viewer-container iframe {
height: 400px;
}
.file-action-btn {
margin-bottom: 8px;
}
}
</style>
@if(empty($files))
<div class="no-files-message">
<i class="fa fa-folder-open fa-3x mb-3"></i>
<h5>No files found in this folder</h5>
<p>Path: {{ $folderPath }}</p>
</div>
@else
<div class="file-grid-container">
<div id="fileDataGrid"></div>
</div>
<div class="pdf-viewer-container" id="pdfViewerContainer" style="display: none;">
<div class="pdf-viewer-header">
<h6>
<i class="fa fa-file-pdf"></i>
<span id="pdfFileName">PDF Viewer</span>
</h6>
<button type="button" class="pdf-viewer-close" onclick="closePdfViewer()">
<i class="fa fa-times"></i>
</button>
</div>
<iframe id="pdfViewer" src=""></iframe>
</div>
@endif
<script>
@if(!empty($files))
$(document).ready(function() {
var fileData = @json($files);
$("#fileDataGrid").dxDataGrid({
dataSource: fileData,
keyExpr: "id",
showBorders: true,
filterRow: {
visible: true
},
searchPanel: {
visible: true,
placeholder: "Search files..."
},
paging: {
pageSize: 10
},
pager: {
showPageSizeSelector: true,
allowedPageSizes: [5, 10, 20, 50],
showInfo: true,
infoText: "Showing {0}-{1} of {2} files"
},
sorting: {
mode: "multiple"
},
columnAutoWidth: true,
rowAlternationEnabled: true,
hoverStateEnabled: true,
showColumnLines: true,
showRowLines: true,
columns: [
{
dataField: "name",
caption: "File Name",
cellTemplate: function(container, options) {
var icon = '';
var iconClass = '';
if (options.data.type === 'Excel') {
icon = '<i class="fa fa-file-excel"></i>';
iconClass = 'text-success';
} else if (options.data.type === 'PDF') {
icon = '<i class="fa fa-file-pdf"></i>';
iconClass = 'text-danger';
} else {
icon = '<i class="fa fa-file"></i>';
iconClass = 'text-secondary';
}
container.html('<span class="' + iconClass + '">' + icon + '</span> <strong>' + options.data.name + '</strong>');
}
},
{
dataField: "type",
caption: "Type",
width: 80
},
{
dataField: "size",
caption: "Size",
width: 100,
dataType: "number",
format: function(value) {
if (value < 1024) return value + ' B';
if (value < 1024 * 1024) return (value / 1024).toFixed(1) + ' KB';
return (value / (1024 * 1024)).toFixed(1) + ' MB';
}
},
{
dataField: "modified",
caption: "Modified",
width: 150,
dataType: "datetime",
format: "dd.MM.yyyy HH:mm"
},
{
caption: "Actions",
width: 150,
cellTemplate: function(container, options) {
var html = '';
// Download button for Excel files
if (options.data.type === 'Excel') {
html += '<button class="btn btn-success btn-sm file-action-btn" onclick="downloadFile(\'' + options.data.path + '\', \'' + options.data.name + '\')" title="Download Excel">';
html += '<i class="fa fa-download"></i> Download';
html += '</button>';
}
// View button for PDF files
if (options.data.type === 'PDF') {
html += '<button class="btn btn-danger btn-sm file-action-btn" onclick="viewPdf(\'' + options.data.path + '\', \'' + options.data.name + '\')" title="View PDF">';
html += '<i class="fa fa-eye"></i> View';
html += '</button>';
}
container.html(html);
}
}
],
summary: {
totalItems: [{
column: "name",
summaryType: "count",
displayFormat: "Total: {0} files"
}]
}
});
});
@endif
function downloadFile(filePath, fileName) {
var downloadUrl = '{{ url("storage/") }}/' + filePath;
var link = document.createElement('a');
link.href = downloadUrl;
link.download = fileName;
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// Başarı mesajı göster
DevExpress.ui.notify('File download started: ' + fileName, 'success', 3000);
}
function viewPdf(filePath, fileName) {
var pdfUrl = '{{ url("storage/") }}/' + filePath;
$('#pdfFileName').text(fileName);
$('#pdfViewer').attr('src', pdfUrl);
$('#pdfViewerContainer').show();
// Scroll to PDF viewer
$('#pdfViewerContainer')[0].scrollIntoView({ behavior: 'smooth' });
// Başarı mesajı göster
DevExpress.ui.notify('PDF opened: ' + fileName, 'success', 3000);
}
function closePdfViewer() {
$('#pdfViewerContainer').hide();
$('#pdfViewer').attr('src', '');
// Başarı mesajı göster
DevExpress.ui.notify('PDF viewer closed', 'info', 2000);
}
</script>
@@ -0,0 +1,329 @@
<?php
/**
* @api-readonly
* Returns document history
*/
use App\Models\DocumentHistory;
$request = request();
$table = $request->input('table');
$column = $request->input('column');
$row_id = $request->input('row_id');
$file_name = $request->input('file_name');
// Document history verilerini DocumentHistory modelinden çek
$query = DocumentHistory::query();
if ($file_name) {
// File name'e göre arama
$file_name = str_replace(".pdf", "", $file_name);
$query->where('file_name', 'LIKE', '%' . $file_name . '%');
} else {
// Table, column, row_id'ye göre arama
$query->where('table_name', $table)
->where('column_name', $column)
->where('row_id', $row_id);
}
$documentHistory = $query->orderBy('action_date', 'DESC')
->get()
->map(function($item) {
return [
'id' => $item->id,
'user_name' => $item->user_name,
'action' => $item->action,
'file_name' => $item->file_name,
'file_size' => $item->file_size,
'moved_from' => $item->moved_from,
'moved_to' => $item->moved_to,
'action_date' => $item->action_date,
'file_path' => $item->file_path,
'notes' => $item->notes
];
})
->toArray();
$historyJson = json_encode($documentHistory);
?>
<style>
.document-history-container {
padding: 10px;
}
.history-info {
background: #f8f9fa;
padding: 10px;
border-radius: 5px;
margin-bottom: 15px;
font-size: 14px;
}
.action-buttons {
display: flex;
gap: 5px;
}
.btn-action {
padding: 3px 8px;
font-size: 11px;
border-radius: 3px;
text-decoration: none;
color: white;
}
.btn-view {
background-color: #17a2b8;
}
.btn-download {
background-color: #28a745;
}
.btn-view:hover {
background-color: #138496;
color: white;
}
.btn-download:hover {
background-color: #218838;
color: white;
}
#documentHistoryGrid {
height: 400px;
margin-top: 10px;
width: 100%;
}
.document-history-container {
width: 100%;
max-width: 100%;
}
.document-history-container .dx-datagrid {
width: 100% !important;
}
</style>
<div class="document-history-container">
<div class="history-info">
@if($file_name)
<strong>Document History for File:</strong> {{ $file_name }}
@else
<strong>Document History for:</strong> {{ $table }}.{{ $column }} (Row ID: {{ $row_id }})
@endif
</div>
<div id="documentHistoryGrid"></div>
</div>
<script>
$(document).ready(function() {
var historyData = {!! $historyJson !!};
$("#documentHistoryGrid").dxDataGrid({
dataSource: historyData,
keyExpr: "id",
allowColumnResizing: true,
allowColumnReordering: true,
showBorders: true,
showRowLines: true,
rowAlternationEnabled: true,
searchPanel: {
visible: true,
width: 240,
placeholder: "Search in history..."
},
headerFilter: {
visible: true
},
filterRow: {
visible: true
},
paging: {
pageSize: 10
},
pager: {
showPageSizeSelector: true,
allowedPageSizes: [5, 10, 20, 50],
showInfo: true
},
columnAutoWidth: false,
columnResizingMode: 'widget',
columns: [
{
dataField: "id",
caption: "ID",
width: 60,
minWidth: 50,
alignment: "center"
},
{
dataField: "user_name",
caption: "User",
width: 120,
minWidth: 80
},
{
dataField: "action",
caption: "Action",
width: 80,
minWidth: 70,
cellTemplate: function(container, options) {
var action = options.value;
var badgeClass = '';
switch(action) {
case 'Upload':
badgeClass = 'badge-success';
break;
case 'Download':
badgeClass = 'badge-primary';
break;
case 'Archive':
badgeClass = 'badge-warning';
break;
case 'Delete':
badgeClass = 'badge-danger';
break;
default:
badgeClass = 'badge-secondary';
}
container.html('<span class="badge ' + badgeClass + '">' + action + '</span>');
}
},
{
dataField: "file_name",
caption: "File Name",
width: 250,
minWidth: 150
},
{
dataField: "file_size",
caption: "Size",
width: 80,
minWidth: 60,
alignment: "center"
},
{
dataField: "moved_from",
caption: "From",
width: 80,
minWidth: 60,
alignment: "center"
},
{
dataField: "moved_to",
caption: "To",
width: 80,
minWidth: 60,
alignment: "center"
},
{
dataField: "action_date",
caption: "Date & Time",
width: 140,
minWidth: 120,
dataType: "datetime",
format: "dd/MM/yyyy HH:mm"
},
{
dataField: "notes",
caption: "Notes",
width: 200,
minWidth: 100
},
{
caption: "Actions",
width: 100,
minWidth: 80,
allowSorting: false,
allowFiltering: false,
cellTemplate: function(container, options) {
var data = options.data;
var actionsHtml = '<div class="action-buttons">';
// View button
actionsHtml += '<a href="#" class="btn-action btn-view" onclick="viewDocument(\'' + data.file_path + '\', \'' + data.file_name + '\')" title="View Document">';
actionsHtml += '<i class="fa fa-eye"></i>';
actionsHtml += '</a>';
// Download button
actionsHtml += '<a href="#" class="btn-action btn-download" onclick="downloadDocument(\'' + data.file_path + '\', \'' + data.file_name + '\')" title="Download Document">';
actionsHtml += '<i class="fa fa-download"></i>';
actionsHtml += '</a>';
actionsHtml += '</div>';
container.html(actionsHtml);
}
}
],
onRowPrepared: function(e) {
if (e.rowType === "data") {
// Silinen dosyalar için farklı stil
if (e.data.action === "Delete") {
e.rowElement.css("background-color", "#ffe6e6");
}
}
}
});
});
// Document view function
function viewDocument(filePath, fileName) {
// Doğru URL oluştur
var viewUrl = buildFileUrl(filePath);
// PDF viewer modal açma
Swal.fire({
title: 'View Document: ' + fileName,
html: '<iframe src="' + viewUrl + '" width="100%" height="500px" frameborder="0"></iframe>',
width: '90%',
showCloseButton: true,
showConfirmButton: false,
customClass: {
popup: 'pdf-viewer-popup'
}
});
}
// Document download function
function downloadDocument(filePath, fileName) {
// Doğru URL oluştur
var downloadUrl = buildFileUrl(filePath);
// Download işlemi
var link = document.createElement('a');
link.href = downloadUrl;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// Success message
Swal.fire({
icon: 'success',
title: 'Download Started',
text: fileName + ' is being downloaded.',
timer: 2000,
showConfirmButton: false
});
}
// Helper function to build correct file URL
function buildFileUrl(filePath) {
// Base URL'i temizle
var cleanPath = filePath.replace(/^\/+/, '');
// Eğer dosya yolu zaten storage/documents/ ile başlıyorsa
if (cleanPath.startsWith('storage/documents/')) {
return "{{ url('/') }}/" + cleanPath;
}
// Tüm dosya yollarını storage/documents/ altında organize et
else {
return "{{ url('storage/documents') }}/" + cleanPath;
}
}
</script>
@@ -0,0 +1,47 @@
@php
use App\Models\DocumentManagerPermission;
$userLevel = $request->get('user_level', 'Admin');
$folderPath = $request->get('folder_path', '');
if (!$userLevel || !$folderPath) {
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'User level and folder path are required']);
exit;
}
try {
// Get all permissions for specific user level and folder (both allowed and denied)
$allPermissions = DocumentManagerPermission::where('user_level', $userLevel)
->where('folder_path', $folderPath)
->get();
// Create array with all permission types and their status
$permissions = [];
$permissionTypes = ['read', 'write'];
foreach ($permissionTypes as $permissionType) {
$permission = $allPermissions->where('permission_type', $permissionType)->first();
if ($permission && $permission->is_allowed) {
$permissions[] = $permissionType;
}
}
// No inheritance - only return explicit permissions for each folder
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'permissions' => $permissions,
'user_level' => $userLevel,
'folder_path' => $folderPath
]);
} catch (Exception $e) {
header('Content-Type: application/json');
echo json_encode([
'success' => false,
'message' => 'Error loading folder permissions: ' . $e->getMessage()
]);
}
@endphp
@@ -0,0 +1,141 @@
@php
use App\Models\DocumentManagerPermission;
use App\Services\DocumentManager\FolderCatalog;
$userLevel = $request->input('user_level', 'Admin');
if (!$userLevel) {
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'User level is required']);
exit;
}
try {
// Get all permissions for this user level
$allPermissions = DocumentManagerPermission::where('user_level', $userLevel)->get();
$catalogService = app(FolderCatalog::class);
$definedFolders = $catalogService->flattened();
$definedPaths = $definedFolders->pluck('path')->map(fn($path) => trim($path, '/'))->filter()->unique()->values();
// Start with catalog defined folders (in declared order)
$allFoldersCollection = collect($definedPaths->all());
// Get all folders from documents directory (not just from permissions)
$documentsPath = storage_path('documents');
$actualFolders = [];
// Debug: Check if path exists
if (!is_dir($documentsPath)) {
header('Content-Type: application/json');
echo json_encode([
'success' => false,
'message' => 'Documents directory not found at: ' . $documentsPath
]);
exit;
}
// Get system folder patterns from config for filtering when needed
$exactMatches = config('document-folders.system_patterns.exact', []);
$regexPatterns = config('document-folders.system_patterns.regex', []);
$items = scandir($documentsPath);
foreach ($items as $item) {
if ($item !== '.' && $item !== '..' && is_dir($documentsPath . '/' . $item)) {
// Filter system folders for non-admin users
if ($userLevel !== 'Admin') {
$isSystemFolder = in_array($item, $exactMatches);
if (!$isSystemFolder) {
foreach ($regexPatterns as $pattern) {
if (preg_match($pattern, $item)) {
$isSystemFolder = true;
break;
}
}
}
if ($isSystemFolder) {
continue; // Skip system folders for non-admin
}
}
// Add main folder
$actualFolders[] = $item;
// Check for subfolders (one level deep)
$subPath = $documentsPath . '/' . $item;
if (is_dir($subPath)) {
$subItems = scandir($subPath);
foreach ($subItems as $subItem) {
if ($subItem !== '.' && $subItem !== '..' && is_dir($subPath . '/' . $subItem)) {
if ($userLevel !== 'Admin') {
$target = $subItem;
$isSystemSub = in_array($target, $exactMatches);
if (!$isSystemSub) {
foreach ($regexPatterns as $pattern) {
if (preg_match($pattern, $target) || preg_match($pattern, $item . '/' . $target)) {
$isSystemSub = true;
break;
}
}
}
if ($isSystemSub) {
continue;
}
}
// Add subfolder with parent folder prefix
$actualFolders[] = $item . '/' . $subItem;
}
}
}
}
}
$actualCollection = collect($actualFolders)->unique()->values();
$extras = $actualCollection->diff($definedPaths)->sort()->values();
$allFoldersCollection = $allFoldersCollection->merge($extras)->unique();
if ($allFoldersCollection->isEmpty()) {
header('Content-Type: application/json');
echo json_encode([
'success' => false,
'message' => 'No folders are defined in the catalog or found on disk.'
]);
exit;
}
$allFolders = $allFoldersCollection->values()->all();
// Get permission types (2-tier system)
$permissionTypes = ['read', 'write'];
$permissions = [];
foreach ($allFolders as $folder) {
$permissions[$folder] = [];
foreach ($permissionTypes as $permissionType) {
$permission = $allPermissions->where('folder_path', $folder)
->where('permission_type', $permissionType)
->first();
if ($permission && $permission->is_allowed) {
$permissions[$folder][] = $permissionType;
}
}
}
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'folders' => $allFolders,
'permissions' => $permissions,
'user_level' => $userLevel
]);
} catch (Exception $e) {
header('Content-Type: application/json');
echo json_encode([
'success' => false,
'message' => 'Error loading permissions: ' . $e->getMessage()
]);
}
@endphp
@@ -0,0 +1,84 @@
@php
use App\Models\DocumentManagerPermission;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
$userLevel = $request->get('user_level');
$permissionsJson = $request->get('permissions', '{}');
$permissions = json_decode($permissionsJson, true) ?: [];
if (!$userLevel) {
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'User level is required']);
exit;
}
try {
DB::beginTransaction();
// 1. Delete ALL existing permissions for this user level
// This is the most reliable way to ensure "unchecked" permissions are removed
DocumentManagerPermission::where('user_level', $userLevel)->delete();
\Log::info("Deleted all existing permissions for user level", ['user_level' => $userLevel]);
// 2. Insert ONLY the permissions sent in the request
// We only store "Allow" permissions. Absence of a record means "No Explicit Permission"
// (which falls back to inheritance or default deny)
$insertCount = 0;
foreach ($permissions as $folderPath => $types) {
// Skip if types is not an array or empty
if (!is_array($types) || empty($types)) {
continue;
}
foreach ($types as $permissionType) {
// Only allow valid permission types
if (!in_array($permissionType, ['read', 'write'])) {
continue;
}
DocumentManagerPermission::create([
'user_level' => $userLevel,
'folder_path' => $folderPath,
'permission_type' => $permissionType,
'is_allowed' => true // We only save TRUE permissions
]);
$insertCount++;
}
}
DB::commit();
// Clear cache for this user level
DocumentManagerPermission::clearPermissionCache($userLevel);
// Log permission changes
\Log::info('Document Manager Permissions Updated', [
'user_level' => $userLevel,
'updated_by' => Auth::user()->id ?? 'Unknown',
'inserted_records' => $insertCount,
'folders_count' => count($permissions)
]);
// Clear cache after saving permissions
Cache::flush();
\App\Models\DocumentManagerPermission::clearAllCaches();
header('Content-Type: application/json');
echo json_encode(['success' => true, 'message' => 'Permissions saved successfully']);
} catch (Exception $e) {
DB::rollback();
\Log::error("Error saving permissions", [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Error saving permissions: ' . $e->getMessage()]);
}
@endphp
@@ -0,0 +1,51 @@
<?php
use Barryvdh\DomPDF\Facade\Pdf;
$pdf = App::make('dompdf.wrapper');
$pdf->setPaper('A4','portrait');
$documentInfo = document_template(get("document_id"));
$data = db(get("table_name"))->where("id", get("id"))->first();
$users = usersArray();
$fileName = $data->ndt_release_no;
?>
<?php
$start = '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body{
font-family: DejaVu Sans;
}
table,tr,td {
border:solid 1px #000 !important;
}
* {
font-size:12px;
}
</style>
</head>
<body>';
$end = "</body>
</html>";
$document = $start . $documentInfo->html . $end;
$document = str_replace("{today}", date("d/m/Y"), $document);
foreach($data AS $column => $value) {
if($column == "spool_ndt_check") {
if(isset($users[$value])) {
$value = $users[$value]->name;
}
}
$document = str_replace("{" . $column . "}", $value, $document);
}
echo $document;
$path = "004_QA/0009_Spool_Release_Check_List";
html_create("$path/$fileName", $document);
?>
@@ -0,0 +1,10 @@
<?php
$string = get("string");
//$string = strtoupper($string);
$pattern = get("regex") ;
//$pattern = str_replace("***", "[.,-_]", $pattern);
preg_match($pattern, $string, $matches);
///Rev[-_\s]?(\d+)/
//dump($_GET);
dump($matches);
?>
@@ -0,0 +1,306 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
use App\Models\DocumentRevision;
use App\Models\WeldLog;
use App\Models\DocumentHistory;
// Permission control for NDT report uploads and Incoming Control
$tableName = $request->input('table_name', null);
$permissionMapping = [
'v_t_logs' => 'vt_log_upload_permission',
'radiographic_tests' => 'rt_log_upload_permission',
'p_t_logs' => 'pt_log_upload_permission',
'magnetic_tests' => 'mt_log_upload_permission',
'p_w_h_t_s' => 'pwht_log_upload_permission',
'hardness_tests' => 'ht_log_upload_permission',
'p_m_i_tests' => 'pmi_log_upload_permission',
'ultrasonic_tests' => 'ut_log_upload_permission',
'ferrits' => 'ferrite_log_upload_permission',
'incoming_controls' => 'incoming_control_upload_permission',
];
if ($tableName && isset($permissionMapping[$tableName])) {
$permissionKey = $permissionMapping[$tableName];
$allowedLevels = j(setting($permissionKey));
$userLevel = Auth::user()->level ?? null;
if (is_array($allowedLevels) && !in_array($userLevel, $allowedLevels)) {
http_response_code(403);
die(json_encode([
'status' => 'error',
'message' => 'You do not have permission to upload files for this module.'
]));
}
}
/*
$post = $request->all();
$folder = post("folder");
$ext = strtolower($request->file->getClientOriginalExtension());
$name = $request->file->getClientOriginalName();
$name = str_replace(".PDF", ".pdf", $name);
$path = $request->file->storeAs($folder, $name);
$path = $request->file->storeAs($folder, $name);
$onlyFileName = str_replace('.' . $ext, "", $name);
$onlyFileName = strtoupper($onlyFileName);
*/
//$onlyFileName = explode(" ", $onlyFileName)[0];
$post = $request->all();
$folder = $request->input("folder");
$ext = strtolower($request->file('file')->getClientOriginalExtension());
$name = $request->file('file')->getClientOriginalName();
$name = str_replace(".PDF", ".pdf", $name);
$onlyFileName = str_replace('.' . $ext, "", $name);
$onlyFileName = strtoupper($onlyFileName);
// Define the path
$cleanFolder = trim($folder, '/');
$fullPath = $cleanFolder . '/' . $name;
// Store the file using Storage::put
// Check for existing files that match the base name (ignoring Rev suffixes)
$uploadedBaseName = pathinfo($name, PATHINFO_FILENAME);
// Remove " Rev" suffix to get the root name (e.g. "DocName Rev4" -> "DocName")
$uploadedRootName = preg_replace('/\sRev.*$/i', '', $uploadedBaseName);
// Get all files in the directory
$allFiles = Storage::files($folder);
foreach ($allFiles as $existingFile) {
$existingFileName = basename($existingFile);
$existingBaseName = pathinfo($existingFileName, PATHINFO_FILENAME);
$existingRootName = preg_replace('/\sRev.*$/i', '', $existingBaseName);
// If the root names match, archive the existing file
if ($existingRootName === $uploadedRootName) {
// Eski dosyayı arşivle
$currentDateTime = Carbon::now()->format('Y_m_d_H_i_s');
$fileExtension = pathinfo($existingFileName, PATHINFO_EXTENSION);
// Archive klasör yapısı: Archive/{original_folder}/{file_name_folder}/{file_name}_{datetime}.{ext}
$archiveFolder = 'Archive/' . $folder . '/' . $existingRootName;
$archivedFileName = $existingBaseName . '_' . $currentDateTime . '.' . $fileExtension;
$archivedPath = $archiveFolder . '/' . $archivedFileName;
// Archive klasörünü oluştur
if (!Storage::exists($archiveFolder)) {
Storage::makeDirectory($archiveFolder);
}
// Eski dosyayı arşive taşı
Storage::move($existingFile, $archivedPath);
// Document history tablosuna kayıt ekle
DocumentHistory::create([
'file_name' => $existingFileName,
'file_path' => $archivedPath,
'user_name' => Auth::user()->name ?? 'System',
'action' => 'Archive',
'file_size' => Storage::exists($archivedPath) ? round(Storage::size($archivedPath) / 1024, 2) . ' KB' : 'Unknown',
'moved_from' => $existingFile,
'moved_to' => $archivedPath,
'action_date' => Carbon::now(),
'table_name' => $request->input('table_name', null),
'column_name' => $request->input('column_name', null),
'row_id' => $request->input('row_id', null),
'notes' => 'File replaced with new version and archived'
]);
}
}
Storage::put($folder . '/' . $name, file_get_contents($request->file('file')->getRealPath()));
// Yeni dosya upload edildiğinde history kaydı ekle
DocumentHistory::create([
'file_name' => $name,
'file_path' => $folder . '/' . $name,
'user_name' => Auth::user()->name ?? 'System',
'action' => 'Upload',
'file_size' => $request->file('file')->getSize() ? round($request->file('file')->getSize() / 1024, 2) . ' KB' : 'Unknown',
'moved_from' => 'Local',
'moved_to' => $folder,
'action_date' => Carbon::now(),
'table_name' => $request->input('table_name', null),
'column_name' => $request->input('column_name', null),
'row_id' => $request->input('row_id', null),
'notes' => 'New file uploaded to server'
]);
if(postisset("table_name")) {
$tableName = post("table_name");
if($tableName == "weld_logs") {
$lineNumber = $name;
$lineNumber = str_replace(".pdf", "", $lineNumber);
dump($lineNumber);
?>
@include("cron.pdf-db-sync", ["lineNumber" => $lineNumber])
@include("cron.document_revisions-pdf-db-document-revisions-sync", [
"lineNumber" => $lineNumber,
])
<?php
}
// document_revisions için sync
if ($tableName == "document_revisions") {
$lineNumber = $name;
$lineNumber = str_replace(".pdf", "", $lineNumber);
dump($lineNumber);
?>
@include("cron.document_revisions-pdf-db-document-revisions-sync", [
"lineNumber" => $lineNumber,
])
<?php
}
if ($tableName == "incoming_control_paints") {
$lineNumber = $name;
$lineNumber = str_replace(".pdf", "", $lineNumber);
// dump($lineNumber);
?>
@include("cron.incoming_control_paints-pdf-db-incoming-control-sync", [
"lineNumber" => $lineNumber,
])
<?php
}
$logTables = array_values(log_test_types());
if (in_array($tableName, $logTables)) {
// tableName logTables içinde mevcut
// Burada gerekli işlemleri yapabilirsiniz
$logTable = $tableName;
$logName = get_key_by_value($tableName);
$fileName = $name;
$fileName = str_replace(".pdf", "", $fileName);
?>
@include("cron.pdf-db-ndt-sync", [
"logTable" => $logTable,
"logName" => $logName,
"fileName" => $fileName,
])
<?php
}
// incoming_controls için sync
if ($tableName == "incoming_controls") {
?>
@include("cron.pdf-db-incoming-control-sync", [
"fileName" => $onlyFileName,
])
<?php
}
if ($tableName == "naks_certificates") {
?>
@include("cron.pdf-db-naks-technology-sync", [
"fileName" => $onlyFileName,
])
<?php
}
if ($tableName == "naks_consumables") {
?>
@include("cron.pdf-db-naks-consumables-sync", [
"fileName" => $onlyFileName,
])
<?php
}
if ($tableName == "supports") {
?>
@include("cron.pdf-db-support-sync", [
"fileName" => $onlyFileName
])
<?php
}
if ($tableName == "i_t_p_s") {
?>
@include("cron.pdf-db-itp-sync", [
"fileName" => $onlyFileName
])
<?php
}
if ($tableName == "document_procedures") {
?>
@include("cron.pdf-db-document-procedure-sync", [
"fileName" => $onlyFileName
])
<?php
}
// Calibration Log - sync uploaded calibration certificates with calibration_logs table
if ($tableName == "calibration_logs") {
?>
@include("cron.pdf-db-calibration-logs-sync", [
"fileName" => $onlyFileName,
])
<?php
}
if ($tableName == "r_f_i_s") {
?>
@include("cron.pdf-db-rfi-sync", [
"folder" => $folder,
"fileName" => $name,
])
<?php
}
}
if(getesit("module","document-revision")) {
$revNoRegexPattern = "/(?i)(Rev|Rev.|Рев|Рев.)(.\d{2}.\d{2}|00.\d{2}|\d{2}_.\d{2}|\d{2})/";
$area = explode("-", $onlyFileName)[0];
preg_match($revNoRegexPattern, $onlyFileName, $revNoMatches);
dump($onlyFileName);
dump($revNoRegexPattern);
dump($revNoMatches);
$revisionNo = $revNoMatches[2] ?? null;
$allRevisionNo = $revNoMatches[0] ?? null;
if($allRevisionNo != "") {
$drawingNo = str_replace("-" . $allRevisionNo, "", $onlyFileName);
} else {
$drawingNo = $onlyFileName;
}
$drawingNo = str_replace($allRevisionNo, "", $drawingNo);
if($folder == "001_Drawings/001_Engineering") {
$documentRevisionData = [
'area' => $area,
'transmittal_document' => post("transmittal_document"),
'publish_date' => post("publish_date"),
'zone' => post("zone"),
'subcontructer' => post("subcontractor"),
'drawing_no' => $drawingNo,
'revision_no' => $revisionNo
];
dump($documentRevisionData);
DocumentRevision::firstOrCreate($documentRevisionData);
dump($documentRevisionData);
}
}
echo "storage/documents/" . $fullPath;
$return = null;
@@ -0,0 +1,165 @@
@php
/**
* Dynamic Resources API - Admin Ajax Endpoint
*
* Auth-protected endpoint for dynamic resource operations.
* Replaces the unauthenticated web.php routes.
*
* Usage:
* /admin-ajax/dynamic-resources?action=tables
* /admin-ajax/dynamic-resources?action=columns&table=TABLE_NAME
* /admin-ajax/dynamic-resources?action=values&table=TABLE_NAME&column=COLUMN_NAME
* /admin-ajax/dynamic-resources?action=calculate&table=TABLE_NAME (POST: column, operation, filter)
*/
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
$action = $request->input('action', '');
$table = $request->input('table', '');
try {
switch ($action) {
case 'tables':
// List all available tables with module info
$dbTables = [];
foreach (DB::select('SHOW TABLES') as $t) {
$dbTables[] = array_values((array)$t)[0];
}
$modules = DB::table('types')
->where('enabled', true)
->whereNotNull('slug')
->where('slug', '!=', '')
->get(['id', 'slug', 'title']);
$moduleMap = [];
foreach ($modules as $module) {
$tableName = Str::snake($module->slug);
$moduleMap[$tableName] = $module;
}
$tables = [];
foreach ($dbTables as $tableName) {
$entry = [
'table_name' => $tableName,
];
if (isset($moduleMap[$tableName])) {
$mod = $moduleMap[$tableName];
$entry['id'] = $mod->id;
$entry['slug'] = $mod->slug;
$entry['title'] = $mod->title;
$entry['is_module'] = true;
} else {
$entry['is_module'] = false;
}
$tables[] = $entry;
}
response()->json(['status' => 'success', 'data' => $tables])->send();
exit();
break;
case 'columns':
// Get columns for a specific table
if (!$table || !Schema::hasTable($table)) {
echo json_encode(['error' => "Table '$table' not found"], JSON_UNESCAPED_UNICODE);
break;
}
$columns = Schema::getColumnListing($table);
response()->json(['status' => 'success', 'table' => $table, 'data' => $columns])->send();
exit();
break;
case 'values':
// Get distinct values for a specific column
$column = $request->input('column');
if (!$column) {
echo json_encode(['error' => 'Column param is required']);
break;
}
if (!Schema::hasTable($table)) {
echo json_encode(['error' => "Table '$table' not found"]);
break;
}
if (!Schema::hasColumn($table, $column)) {
echo json_encode(['error' => "Column '$column' not found"]);
break;
}
$values = DB::table($table)
->select($column)
->distinct()
->orderBy($column)
->limit(100)
->pluck($column);
response()->json(['status' => 'success', 'table' => $table, 'column' => $column, 'data' => $values])->send();
exit();
break;
case 'calculate':
// Calculate aggregates
$column = $request->input('column');
$operation = strtolower($request->input('operation', 'count'));
$filter = $request->input('filter');
if (!$column && $operation !== 'count') {
echo json_encode(['error' => 'Column is required for this operation']);
break;
}
$allowedOperations = ['sum', 'avg', 'min', 'max', 'count'];
if (!in_array($operation, $allowedOperations)) {
echo json_encode(['error' => 'Invalid operation']);
break;
}
if (!Schema::hasTable($table)) {
echo json_encode(['error' => "Table '$table' not found"]);
break;
}
$query = DB::table($table);
// Apply Filters via QueryBuilderService
if ($filter) {
$queryBuilder = app(\App\Services\QueryBuilderService::class);
$query = $queryBuilder->apply($query, $filter);
}
if ($operation === 'count') {
$result = $query->count();
} else {
if (!Schema::hasColumn($table, $column)) {
echo json_encode(['error' => "Column '$column' does not exist in table '$table'"]);
break;
}
$castedColumn = DB::raw("CAST(`$column` AS DECIMAL(20, 2))");
switch ($operation) {
case 'sum': $result = $query->sum($castedColumn); break;
case 'avg': $result = $query->avg($castedColumn); break;
case 'min': $result = $query->min($castedColumn); break;
case 'max': $result = $query->max($castedColumn); break;
}
}
response()->json([
'table' => $table,
'operation' => $operation,
'column' => $column,
'result' => $result,
'status' => 'success'
])->send();
exit();
break;
default:
echo json_encode(['error' => 'Invalid action. Use: tables, columns, values, calculate']);
break;
}
} catch (\Exception $e) {
echo json_encode(['error' => $e->getMessage()]);
}
@endphp
@@ -0,0 +1,19 @@
<?php
/**
* @api-readonly
* Returns employee list with basic info
*/
$users = db("users")
->select(
"id",
"pic",
"name",
"name_ru",
"registration_no AS welder_id",
"subcontructer",
)
->whereIn("level", ['Welder'])
->get();
echo json_encode_tr($users);
@@ -0,0 +1,79 @@
<?php
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Writer\Html;
use Mpdf\Mpdf;
// Excel dosyasını yükle
try {
$filePath = 'storage/documents/test/test.xlsx';
$spreadsheet = IOFactory::load($filePath);
// Değiştirilecek joker alanlar ve değerleri
$replacements = [
'{test1}' => 'Deger1',
'{test2}' => 'Deger2',
'{test3}' => 'Deger3',
// Diğer joker alanlar ve değerler buraya eklenebilir
];
// Aktif çalışma sayfasını al
$sheet = $spreadsheet->getActiveSheet();
// Tüm hücreleri döngüyle gezerek joker alanları değiştir
foreach ($sheet->getRowIterator() as $row) {
foreach ($row->getCellIterator() as $cell) {
$cellValue = $cell->getValue();
if (is_string($cellValue)) {
foreach ($replacements as $search => $replace) {
if (strpos($cellValue, $search) !== false) {
$cellValue = str_replace($search, $replace, $cellValue);
$cell->setValue($cellValue);
}
}
}
}
}
// Değişiklikleri kaydetmek için yeni bir dosya oluştur
$outputFilePath = 'storage/documents/test/output/output.xlsx';
$htmlFilePath = 'storage/documents/test/output/output.html';
$pdfFilePath = 'storage/documents/test/output/output.pdf';
// HTML yazıcı oluştur
$htmlWriter = new Html($spreadsheet);
$htmlWriter->save($htmlFilePath);
$htmlContent = file_get_contents($htmlFilePath);
html_to_pdf($htmlFilePath, $pdfFilePath);
// MPDF ile PDF oluştur
/*
$mpdf = new Mpdf();
$mpdf->WriteHTML($htmlContent);
$mpdf->Output($pdfFilePath, \Mpdf\Output\Destination::FILE);
// Geçici HTML dosyasını sil
unlink($htmlFilePath);
*/
echo "Dosya başarıyla PDF olarak kaydedildi: $pdfFilePath";
/*
$writer = new Xlsx($spreadsheet);
$writer->save($outputFilePath);
echo "Dosya başarıyla kaydedildi: $outputFilePath";
*/
} catch (\Throwable $th) {
echo 'Hata: ' . $th->getMessage();
}
?>
@@ -0,0 +1,24 @@
<?php
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
try {
// Yeni bir elektronik tablo oluştur
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World!');
// Yeni bir Xlsx dosya yazıcı oluştur
$writer = new Xlsx($spreadsheet);
// Dosya yolu
$outputFilePath = 'storage/documents/test/output/output.xlsx';
// Dosyayı kaydet
$writer->save($outputFilePath);
echo "Dosya başarıyla Xlsx olarak kaydedildi: $outputFilePath";
} catch (Exception $e) {
echo 'Hata: ' . $e->getMessage();
}
?>
@@ -0,0 +1,2 @@
<?php
echo json_encode_tr(db("line_lists")->get()->toArray()); ?>
@@ -0,0 +1,4 @@
<?php $prefix = get("table") . "_excel_process";
$excelLogPath = "storage/$prefix.log";
echo file_get_content($excelLogPath);
?>
@@ -0,0 +1,18 @@
<?php
/*
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
*/
$pdfFile = get("file");
/*
$spreadsheet = IOFactory::load(get("file"));
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save($pdfFile);
*/
$fullPath = xlsx_to_pdf_legacy($pdfFile, "storage/documents/013_Others/pdf");
$relativePath = strstr($fullPath, 'storage/documents');
echo url($relativePath);
?>
@@ -0,0 +1,334 @@
<?php
// PHP'nin maksimum çalışma süresini artır
set_time_limit(0); // Sınırsız çalışma süresi ayarla
ini_set('memory_limit', '512M'); // Bellek limitini artır
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Illuminate\Support\Facades\Artisan;
// .env dosyasından veritabanı bilgilerini alın
$user = env("DB_USERNAME");
$password = env("DB_PASSWORD");
$database = env("DB_DATABASE");
$delimiter = ";";
if(!getesit("delimiter", ""))
{
$delimiter = get("delimiter");
}
if(getesit("file_type", "xlsx"))
{
$delimiter = "\t";
}
// Eğer veritabanı bilgileri boş gelirse yapılandırma önbelleğini temizle
if (empty($user) || empty($password) || empty($database)) {
// Config cache'i temizle
Artisan::call('config:clear');
// Cache temizlendikten sonra tekrar env değerlerini al
$user = env("DB_USERNAME");
$password = env("DB_PASSWORD");
$database = env("DB_DATABASE");
}
$columns = "*";
// Bu alanlar Excel'de metin olarak kalmalı (ör: 1/1 gibi değerler için)
$forceStringFields = [
'quantity_of_iso',
'outer_diameter_1',
'outer_diameter_2',
'wall_thickness_1',
'wall_thickness_2',
'total_wdi',
'total_complated_wdi',
'total_shop_wdi',
'total_complated_shop_wdi',
'total_field_wdi',
'total_complated_field_wdi',
'remaining_wdi',
'fluid_code',
'diameter',
];
// Bu alanlar decimal değerlerini virgüllü formatta export etmeli
$forceVirgulFields = [
'nps_1',
'nps_2',
];
if(!getesit("columns", ""))
{
$columns = get("columns");
$columns = base64_decode($columns);
// Sütunları virgülle ayır
$columnsArray = explode(',', $columns);
// Sütun adlarını tırnak içine al
$columnsArray = array_map(function($column) {
$column = trim($column);
return "COALESCE(`" . $column . "`, '') $column"; // Sütun adlarını tırnak içine al
}, $columnsArray);
// Tırnak içine alınmış sütunları tekrar virgüllerle birleştir
$columns = implode(',', $columnsArray);
}
$tableName = get("table_name");
$moduleFileName = get("module");
// Apply employer view filters for weldlog-employer-view module
$whereClause = "";
if($moduleFileName === 'weldlog-employer-view' && $tableName === 'weld_logs') {
// Filter 1: Exclude records with repair_status = 'Repair' in repair_logs
$repairFilter = "NOT EXISTS (
SELECT 1 FROM repair_logs
WHERE repair_logs.iso_number = weld_logs.iso_number
AND repair_logs.new_joint_no = weld_logs.no_of_the_joint_as_per_as_built_survey
AND repair_logs.repair_status = 'Repair'
)";
// Filter 2: Only acceptable NDT results (Accept / Годен, empty, or NULL)
$ndtFields = [
'vt_result',
'rt_result',
'ut_result',
'pt_result',
'mt_result',
'pmi_result',
'ferrite_result',
'ht_result'
];
$ndtFilters = [];
foreach ($ndtFields as $field) {
$ndtFilters[] = "({$field} IN ('Accept / Годен', '') OR {$field} IS NULL)";
}
$ndtFilter = implode(' AND ', $ndtFilters);
$whereClause = " WHERE ({$repairFilter}) AND ({$ndtFilter})";
}
// Create standardized filename: "ProjectCode_ModuleName_Date_Time"
$projectNumber = setting('project_number') ?: 'QMS';
$currentDateTime = now();
$dateStr = $currentDateTime->format('d.m.Y');
$timeStr = $currentDateTime->format('H.i');
$fileName = $projectNumber . '_' . $moduleFileName . '_' . $dateStr . '_' . $timeStr;
// Kayıt yapılacak dosya yolu
$csvPath = storage_path($fileName . '.csv');
@unlink($csvPath);
// MySQL komutunu tanımlayın (sudo olmadan)
$query = "SELECT $columns FROM $tableName" . $whereClause;
// İsteğe bağlı olarak çok büyük veri setlerinde LIMIT eklemek isteyebilirsiniz
// Kullanıcı arayüzünden bir limit parametresi alabilir veya varsayılan bir limit belirleyebilirsiniz
$limit = get("limit", 0); // Varsayılan olarak 0 (tüm veriyi getirir)
if ($limit > 0) {
$query .= " LIMIT $limit";
}
$query .= ";";
// CSV dosyasını başlat
file_put_contents($csvPath, "\xEF\xBB\xBF"); // UTF-8 BOM
// Excel uyumluluğu için tüm alanları tırnak içine al
$excelCompatible = true;
// Doğrudan mysql komutunu çalıştırarak sonuçları CSV formatında alacağız
$mysqlCmd = "/usr/bin/mysql -u " . escapeshellarg($user) .
" -p" . escapeshellarg($password) .
" -D " . escapeshellarg($database) .
" --default-character-set=utf8mb4" .
" -B" . // Batch mode (tab-separated)
" -N" . // No column names
" -e " . escapeshellarg("SET NAMES utf8mb4; $query") .
" 2>/dev/null";
// mysql komutunu çalıştır ve sonuçları satır satır oku
$mysqlHandle = popen($mysqlCmd, 'r');
// Sütun adlarını ayarlamak için işlem yapalım
$csvHeaderColumns = [];
if(!getesit("columns", "")) {
// Özel sütun seçimi varsa, bu sütunların adlarını kullan
$headerColumnsArr = explode(',', base64_decode(get("columns")));
// Sütun adlarını temizle (COALESCE ifadelerini kaldır)
foreach($headerColumnsArr as $colName) {
$colName = trim($colName);
// COALESCE(`column`, '') column formatındaysa, sadece column kısmını al
if(preg_match('/^.*`([^`]+)`.*$/', $colName, $matches)) {
$csvHeaderColumns[] = $matches[1];
} else {
// Değilse doğrudan ismi kullan
$csvHeaderColumns[] = $colName;
}
}
} else {
// Tüm sütunları kullanıyorsa, veritabanından al
$tableInfoCmd = "/usr/bin/mysql -u " . escapeshellarg($user) .
" -p" . escapeshellarg($password) .
" -D " . escapeshellarg($database) .
" --default-character-set=utf8mb4" .
" -e " . escapeshellarg("SHOW COLUMNS FROM $tableName") .
" 2>/dev/null";
// Sütun adlarını al
exec($tableInfoCmd, $columnInfoOutput);
// İlk satırı atla (başlık satırı)
for ($i = 1; $i < count($columnInfoOutput); $i++) {
$parts = preg_split('/\s+/', trim($columnInfoOutput[$i]), 2);
if (!empty($parts[0])) {
$csvHeaderColumns[] = $parts[0];
}
}
}
// Sütun adlarını CSV dosyasına yaz
if (!empty($csvHeaderColumns)) {
// CSV formatında tırnak kullanarak başlık satırını oluştur
// fputcsv ile güvenli CSV header yazma (otomatik escaping)
$csvFile = fopen($csvPath, 'a');
fputcsv($csvFile, $csvHeaderColumns, $delimiter, '"');
fclose($csvFile);
}
// Verileri satır satır oku ve dosyaya yaz
while (($line = fgets($mysqlHandle)) !== false) {
// Satırın sonundaki satır sonu karakterini kaldır
$line = rtrim($line);
// Satırı tab karakterlerine göre böl
$fields = explode("\t", $line);
// Tarih formatlarını düzelt ve decimal alanları virgüllü yap
foreach ($fields as $i => &$field) {
// Eğer bu alan forceStringFields içindeyse, değeri ="değer" olarak yaz
if (isset($csvHeaderColumns[$i]) && in_array($csvHeaderColumns[$i], $forceStringFields)) {
$field = '="' . str_replace('"', '""', $field) . '"';
}
// Eğer bu alan forceVirgulFields içindeyse, decimal değerleri virgüllü yap
elseif (isset($csvHeaderColumns[$i]) && in_array($csvHeaderColumns[$i], $forceVirgulFields)) {
if (!empty($field) && is_numeric($field) && strpos($field, '.') !== false) {
$field = str_replace('.', ',', $field);
}
} else {
// Tarih formatını değiştir
$field = preg_replace_callback(
'/^(\d{4})-(\d{2})-(\d{2})$/',
function ($matches) {
return $matches[3] . '.' . $matches[2] . '.' . $matches[1]; // dd.mm.yyyy formatına
},
$field
);
}
}
$fields = str_replace("\\\\", "\\", $fields);
// fputcsv ile güvenli CSV yazma (otomatik escaping - sütun kaymasını önler)
$csvFile = fopen($csvPath, 'a');
fputcsv($csvFile, $fields, $delimiter, '"');
fclose($csvFile);
}
// mysql process'i kapat
pclose($mysqlHandle);
$fileType = "csv";
if(getesit("file_type", "xlsx"))
{
// XLSX dönüşümü öncesi belleği temizle
gc_collect_cycles();
try {
// LibreOffice ile CSV'den XLSX'e dönüştürme
$outputDir = storage_path();
$outputFilename = "$fileName.xlsx";
// LibreOffice için filtreleme seçenekleri:
// 9 = Tab karakteri ayırıcı olarak kullanıldığını belirt
// 0 = Metin sınırlayıcı karakteri kullanılmadığını belirt (veya ihtiyaca göre değiştirilebilir)
// 76 = Karakter seti (UTF-8)
// 1 = İlk satır başlık
$shellCmd = "libreoffice --headless --infilter=\"Text - txt - csv (StarCalc):9,0,76,1\" --convert-to xlsx --outdir " .
escapeshellarg($outputDir) . " " . escapeshellarg($csvPath) . " 2>&1";
// Komutu çalıştır
$output = [];
$returnCode = 0;
exec($shellCmd, $output, $returnCode);
// Hata kontrolü
if ($returnCode !== 0) {
throw new Exception("LibreOffice conversion failed: " . implode("\n", $output));
}
// LibreOffice dönüştürme işlemi tamamlandıktan sonra, dosyanın doğru adını bulalım
$csvBaseName = basename($csvPath);
$csvFileNameWithoutExt = pathinfo($csvBaseName, PATHINFO_FILENAME);
$expectedXlsxPath = $outputDir . '/' . $csvFileNameWithoutExt . '.xlsx';
// Eğer beklenen dosya yoksa, orijinal dosya adıyla tekrar deneyelim
if (!file_exists($expectedXlsxPath)) {
$expectedXlsxPath = $outputDir . '/' . $fileName . '.xlsx';
}
// Son dosya yolunu saklayalım
$xlsxOutputPath = $expectedXlsxPath;
$fileType = "xlsx";
} catch (Exception $e) {
// XLSX dönüşümü başarısız olursa, CSV dosyasını sunalım
$xlsxResult = ['error' => $e->getMessage()];
$fileType = "csv";
}
}
// CSV dosyasını kontrol et - çok büyükse bile LibreOffice ile dönüştürmeyi dene
$fileSize = filesize($csvPath);
$maxSize = 100 * 1024 * 1024; // 100MB - LibreOffice daha büyük dosyaları işleyebilir
// Çok büyük dosyalar için uyarı logla ama yine de dönüştürmeyi dene
if ($fileSize > $maxSize && $fileType == "xlsx") {
// Büyük dosya işleme durumunu loglayabilirsiniz
error_log("Warning: Processing large file ($fileName.csv) of size " . round($fileSize / (1024 * 1024), 2) . " MB");
}
if(isset($xlsxResult['error']))
{
// Hata durumunda CSV dosyasını sun
error_log("XLSX conversion error: " . $xlsxResult['error']);
yonlendir(url("storage/$fileName.csv"));
} else {
if ($fileType == "xlsx") {
// Dosya adından storage path kısmını çıkar, sadece relatif yolu ve dosya adını al
$relativePath = str_replace(storage_path(), '', $xlsxOutputPath);
// Başındaki slash'ı kaldır
$relativePath = ltrim($relativePath, '/');
yonlendir(url("storage/$relativePath"));
} else {
yonlendir(url("storage/$fileName.$fileType"));
}
}
// İşlem tamamlandıktan sonra belleği temizle
gc_collect_cycles();
// Geçici dosyaları temizle
if ($fileType == "xlsx" && file_exists($csvPath)) {
@unlink($csvPath); // XLSX oluşturulduysa CSV'yi silebiliriz
}
?>
@@ -0,0 +1,29 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use File;
use Illuminate\Support\Facades\DB;
$post = $request->all();
/*
$ext = $request->file->getClientOriginalExtension();
$path = $request->file->storeAs("files/{$post['slug']}",$post['slug']."-".$post['id']."-".rand(111,999).'.'.$ext);
$path = str_replace("files/","",$path);
*/
echo "ok";
oturumAc();
$destinationPath = $post['file'];
echo $destinationPath;
File::delete($destinationPath);
$dizi = $_SESSION['files']; //explode(",",$_SESSION['files']);
foreach($dizi AS $a=>$d) {
if($post['file']==$d) {
unset($dizi[$a]);
}
}
$_SESSION['files'] = $dizi;
print_r(oturum("files"));
$return = null;
@@ -0,0 +1,37 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
$post = $request->all();
$ext = $request->file->getClientOriginalExtension();
$name = $request->file->getClientOriginalName();
$path = $request->file->storeAs("013_Others/files/{$post['slug']}",$name);
$path = str_replace("013_Others/files/","",$path);
$files_path = ("storage/app/013_Others/files/{$post['slug']}")."/???*.*";
$files = glob($files_path);
// print_r($files);
DB::table("contents")
->where('id', $post['id'])
->update(["files" => implode(",",$files)]);
oturumAc();
print_r($files);
//$_SESSION['files'] = $files;
$return = null;
@@ -0,0 +1,4 @@
<?php
oturumAc();
unset($_SESSION['full-screen-block']);
?>
@@ -0,0 +1,4 @@
<?php
oturumAc();
oturum('full-screen-block', get("id"));
?>
@@ -0,0 +1,30 @@
{{-- @api-readonly --}}
<?php
use App\Models\InspectionHistory;
use App\Models\User;
$records = InspectionHistory::where('table_name', 'Other')
->orderBy('id', 'DESC')
->get();
$users = User::all()->pluck('name', 'id')->toArray();
$data = $records->map(function($record) use ($users) {
return [
'id' => $record->id,
'user_name' => $users[$record->user_id] ?? 'Unknown',
'created_at' => $record->created_at->format('d.MM.Y H:i'), // DevExtreme format compatible or ISO
'date' => $record->created_at->toIso8601String(),
'ip_address' => $record->ip_address,
'comment' => $record->comment,
'file_path' => $record->file_path,
'file_name' => $record->file_name,
];
});
echo json_encode([
'status' => 'success',
'data' => $data,
'totalCount' => $records->count()
]);
?>
@@ -0,0 +1,99 @@
<?php
use Barryvdh\DomPDF\Facade\Pdf;
$documentInfo = document_template("isometric-drawing-list");
$j = j($documentInfo->json);
$prefix = "ISOMETRIC-DRAWINGS";
$isometricNo = "$prefix-" . $counter;
$isometricFileName = $isometricNo;
$data = j(post("data"));
$weldLogs = apply_welded_filter(
db("weld_logs")->whereIn("id", array_column($data, 'id'))
)->get();
$totalSpoolJoint = [];
$totalJoint = [];
foreach($weldLogs AS $weldLog) {
if(!isset($totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number]))
$totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number] = 0;
if(!isset($totalJoint[$weldLog->iso_number]))
$totalJoint[$weldLog->iso_number]= 0;
if($weldLog->type_of_joint == "S") {
$totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number]++;
$totalJoint[$weldLog->iso_number]++;
}
}
$k = 1;
$rows = "";
$qc_date1 = "";
$qc_date2 = "";
foreach($weldLogs AS $weldLog) {
$ste_subcontractor =$weldLog->ste_subcontractor;
$general_contractor =$weldLog->general_contractor;
$contractor =$weldLog->contractor;
$qc_date1 = $weldLog->ndt_release_date;
$qc_date2 = $weldLog->ndt_release_date;
$row = "
<tr style='height: 15.0pt;'>
<td align='right'>$k</td>
<td>{$weldLog->iso_number}</td>
<td>{$weldLog->spool_number}</td>
<td>{$weldLog->iso_rev}</td>
<td>Cоответствие</td>
</tr>
";
$rows .= $row;
$k++;
}
$table = "
<table style='font-size:6px;width: 100%;border:solid 1px #000' border='0' cellspacing='0' cellpadding='0'>
<tbody>
<tr>
<td>NO /Номер
</td>
<td>ISOMETRIC NO / Номер чертежа
</td>
<td>SPOOL NO/№ Трубного Узла
</td>
<td>REV. Ревизия
</td>
<td> Result of receiving the spool Результат приемки трубного узла
</td>
</tr>
$rows
</tbody>
</table>
";
$document = pdf_html_content($documentInfo->html);
$document = str_replace("{table_content}", $table, $document);
$document = str_replace("{date}", date("d.m.Y"), $document);
$document = str_replace("{rfi_number}", "-", $document);
$document = str_replace("{representative_staff1}", $ste_subcontractor, $document);
$document = str_replace("{representative_staff2}", $contractor, $document);
$document = str_replace("{qc_date1}", $qc_date1, $document);
$document = str_replace("{qc_date2}", $qc_date2, $document);
$path = "004_QA/0014_Spool_Release_for_Client";
$path = "$path/$folderName/$isometricFileName";
html_create($path, $document, $j['paper']);
?>
@@ -0,0 +1,221 @@
<?php
use Barryvdh\DomPDF\Facade\Pdf;
$documentInfo = document_template("clearance-report");
$j = j($documentInfo->json);
$prefix = "CLR";
$counter = get_counter("CLEARANCE");
$clearance_no = "$prefix-" . $counter;
$folderName = $counter;
$fileName = $clearance_no;
$data = j(post("data"));
$weldLogs = apply_welded_filter(
db("weld_logs")->whereIn("id", array_column($data, 'id'))
)->get();
$totalSpoolJoint = [];
$totalJoint = [];
foreach($weldLogs AS $weldLog) {
if(!isset($totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number]))
$totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number] = 0;
if(!isset($totalJoint[$weldLog->iso_number]))
$totalJoint[$weldLog->iso_number]= 0;
if($weldLog->type_of_joint == "S") {
$totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number]++;
$totalJoint[$weldLog->iso_number]++;
}
apply_welded_filter(
db("weld_logs")
->where("iso_number", $weldLog->iso_number)
->where("spool_number", $weldLog->spool_number)
)->update([
"clearance_no" => $clearance_no,
"clearance_date" => simdi(),
]);
}
$k = 1;
$rows = "";
$isometrics = [];
$ste_subcontractor = "";
$contractor = "";
$general_contractor = "";
foreach($weldLogs AS $weldLog) {
if(!in_array($weldLog->iso_number, $isometrics)) {
$isometrics[] = $weldLog->iso_number;
}
$ste_subcontractor = $weldLog->ste_subcontractor;
$general_contractor =$weldLog->general_contractor;
$contractor =$weldLog->contractor;
$weldLog->welding_date = df($weldLog->welding_date);
$row = "
<tr class='bordered' style='height: 15.0pt;'>
<td align='right'>$k</td>
<td>{$weldLog->iso_number}</td>
<td>{$weldLog->spool_number}</td>
<td>{$weldLog->no_of_the_joint_as_per_as_built_survey}</td>
<td>{$weldLog->wps_no}</td>
<td>{$weldLog->welding_date}</td>
<td>{$weldLog->welder_1}</td>
<td>{$weldLog->welder_2}</td>
<td>{$weldLog->outside_diameter_1}</td>
<td>{$weldLog->wall_thickness_1}</td>
<td>{$weldLog->ndt_percent}</td>
<td>{$totalJoint[$weldLog->iso_number]}</td>
<td>{$totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number]}</td>
<td>{$weldLog->vt_report}</td>
<td>{$weldLog->rt_report} / {$weldLog->ut_report}</td>
<td>{$weldLog->rt_result} / {$weldLog->ut_result}</td>
<td>{$weldLog->mt_report} / {$weldLog->pt_report}</td>
<td>{$weldLog->no_of_pwht_report}</td>
<td>{$weldLog->pwht_date}</td>
<td>{$weldLog->ht_report}</td>
<td>{$weldLog->pmi_report}</td>
<td>{$weldLog->ferrite_result}</td>
<td>{$weldLog->remarks}</td>
</tr>
";
$rows .= $row;
$k++;
}
$table = "
<style>
table * {
font-size:10px !important;
}
</style>
<table style='font-size:6px !important;width: 100%;border:solid 1px #000;' border='0' cellspacing='0' cellpadding='0'>
<tbody>
<tr class='bordered'>
<td>No</td>
<td>Drawing</td>
<td>Spool No</td>
<td>Joint no</td>
<td>WPS no</td>
<td>Weld Date</td>
<td>Welder 1</td>
<td>Welder 2</td>
<td>OD1(mm)</td>
<td>Thck1(mm)</td>
<td>%NDT</td>
<td>Workshop joint quantity
(Line-based)</td>
<td>Workshop joint quantity
(Spool-based)</td>
<td>VT Report no</td>
<td>RT/ UT ReportNo</td>
<td>RT/ UT Status</td>
<td>MT/PT Report NO</td>
<td>PWHT Chart No</td>
<td>PWHT Date</td>
<td>HT Report No</td>
<td>Pmi report</td>
<td>Ferrite Report</td>
<td>Remarks</td>
</tr>
$rows
</tbody>
</table>
";
$document = pdf_html_content($documentInfo->html);
$document = str_replace("{table_content}", $table, $document);
$document = str_replace("{subcontractor}", $ste_subcontractor, $document);
$document = str_replace("{contractor}", $contractor, $document);
$document = str_replace("{third_party}", $ste_subcontractor, $document);
$document = str_replace("{engineering_company}", $general_contractor, $document);
$path = "004_QA/0010_Spool_NDT_Release_Check_List";
$path = "$path/$fileName";
$path2 = "004_QA/0014_Spool_Release_for_Client/$folderName/$fileName";
html_create($path, $document, $j['paper']);
html_create($path2, $document, $j['paper']);
echo url("storage/documents/$path.pdf?" . rand());
$QABasePath = "storage/documents/004_QA";
$clientBasePath = "$QABasePath/0014_Spool_Release_for_Client";
if(postesit("drawing_document", "true")) {
foreach($isometrics AS $isometric) {
$search = glob("storage/documents/001_Drawings/002_Iso/*$isometric*.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/$isometric.pdf");
}
}
}
if(postesit("log_report", "true")) {
foreach($weldLogs AS $weldLog) {
$search = glob("$QABasePath/0000_VT/{$weldLog->vt_report}.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/{$weldLog->vt_report}.pdf");
}
$search = glob("$QABasePath/0001_RT/{$weldLog->rt_report}.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/{$weldLog->rt_report}.pdf");
}
$search = glob("$QABasePath/0002_UT/{$weldLog->ut_report}.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/{$weldLog->ut_report}.pdf");
}
$search = glob("$QABasePath/0003_MT/{$weldLog->mt_report}.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/{$weldLog->mt_report}.pdf");
}
$search = glob("$QABasePath/0004_PT/{$weldLog->pt_report}.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/{$weldLog->pt_report}.pdf");
}
$search = glob("$QABasePath/0005_PMI/{$weldLog->pmi_report}.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/{$weldLog->pmi_report}.pdf");
}
$search = glob("$QABasePath/0006_Ferrite/{$weldLog->ferrite_report}.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/{$weldLog->ferrite_report}.pdf");
}
$search = glob("$QABasePath/0007_PWHT/{$weldLog->no_of_pwht_report}.pdf");
if(isset($search[0])) {
copy($search[0], "$clientBasePath/$folderName/{$weldLog->no_of_pwht_report}.pdf");
}
}
}
?>
@include("admin-ajax.generate-isometric-drawing-list")
@@ -0,0 +1,158 @@
<?php
use Barryvdh\DomPDF\Facade\Pdf;
$documentInfo = document_template("Paint_Release_Register");
$j = j($documentInfo->json);
$paint_release_register_pattern = setting('paint_release_register_pattern');
$counter = get_counter("Paint_Release_Register");
$register_paint_no = str_replace("{number}", $counter, $paint_release_register_pattern);
//$folderName = $counter;
$folderName = "";
$fileName = $register_paint_no;
$data = j(post("data"));
$clientPath = "storage/documents/004_QA/0017_Spool_Release_Paint_For_Client";
$weldLogs = apply_welded_filter(
db("weld_logs")->whereIn("id", array_column($data, 'id'))
)->get();
$totalSpoolJoint = [];
$totalJoint = [];
foreach($weldLogs AS $weldLog) {
if(!isset($totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number]))
$totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number] = 0;
if(!isset($totalJoint[$weldLog->iso_number]))
$totalJoint[$weldLog->iso_number]= 0;
if($weldLog->type_of_joint == "S") {
$totalSpoolJoint[$weldLog->iso_number][$weldLog->spool_number]++;
$totalJoint[$weldLog->iso_number]++;
}
apply_welded_filter(
db("weld_logs")
->where("iso_number", $weldLog->iso_number)
->where("spool_number", $weldLog->spool_number)
)->update([
"register_paint_no" => $register_paint_no,
'register_date' => simdi()
]);
}
$k = 1;
$rows = "";
$isometrics = [];
@mkdir("$clientPath/$folderName/",0777, true);
foreach($weldLogs AS $weldLog) {
if(!in_array($weldLog->iso_number, $isometrics)) {
$isometrics[] = $weldLog->iso_number;
}
$fieldCount = apply_welded_filter(
db("weld_logs")
->where("iso_number", $weldLog->iso_number)
->where("spool_number", $weldLog->spool_number)
->where("type_of_joint", "S")
)->count();
$ste_subcontractor =$weldLog->ste_subcontractor;
$general_contractor =$weldLog->general_contractor;
$contractor =$weldLog->contractor;
$weldLog->paint_release_date = df($weldLog->paint_release_date);
$row = "
<tr class='bordered' style='height: 15.0pt;'>
<td align='right'>$k</td>
<td>{$weldLog->iso_number}</td>
<td>{$weldLog->spool_number}</td>
<td>{$weldLog->no_of_the_joint_as_per_as_built_survey}</td>
<td>{$weldLog->paint_release_no}</td>
<td>{$weldLog->paint_release_date}</td>
<td>{$weldLog->iso_rev}</td>
<td>{$fieldCount}</td>
<td>{$weldLog->main_nps}</td>
<td>Cоответствие</td>
</tr>
";
$searchPath = "storage/documents/004_QA/0016_Spool_Paint_Release_Checklist/{$weldLog->paint_release_no}.pdf";
$search = glob($searchPath);
if(isset($search[0])) {
copy($search[0], "$clientPath/$folderName/{$weldLog->paint_release_no}.pdf");
}
$rows .= $row;
$k++;
}
$table = "
<style>
table * {
font-size:10px !important;
}
</style>
<table style='font-size:6px !important;width: 100%;border:solid 1px #000;margin:20px 0' border='0' cellspacing='0' cellpadding='0'>
<tbody>
<tr class='bordered'>
<td>No <br> Номер</td>
<td>Drawing <br> Номер чертежа</td>
<td>Spool No <br> № Трубного Узла</td>
<td>Joint no <br> стык</td>
<td>Paint Report No <br> Отчет о покраске №</td>
<td>Paint Report Date <br> Дата отчета о покраске</td>
<td>Revision No <br> Ревизия</td>
<td>Quantity of Joint <br> количественное соединение</td>
<td>Main Pipe Size Diammeter <br> размер основной трубы</td>
<td>Result of receiving the spool <br> Результат приемки трубного узл</td>
</tr>
$rows
</tbody>
</table>
";
$document = pdf_html_content($documentInfo->html);
$document = str_replace("{table_content}", $table, $document);
$document = str_replace("{subcontractor}", $ste_subcontractor, $document);
$document = str_replace("{date}", df(simdi()), $document);
$document = str_replace("{register_paint_no}", $register_paint_no, $document);
$document = str_replace("{contractor}", $contractor, $document);
$document = str_replace("{third_party}", $ste_subcontractor, $document);
$document = str_replace("{engineering_company}", $general_contractor, $document);
$path = "004_QA/0017_Spool_Release_Paint_For_Client/$folderName/$fileName";
html_create($path, $document, $j['paper']);
echo url("storage/documents/$path.pdf");
?>
@@ -0,0 +1,30 @@
<?php
use Barryvdh\DomPDF\Facade\Pdf;
$documentInfo = document_template(get("id"));
$j = j($documentInfo->json);
$pageSize = isset($j['page']) ? $j['page'] : "A4";
$pdf = App::make('dompdf.wrapper');
$pdf->setPaper($pageSize, $j['paper']);
$pdf->setOption([
'dpi' => $j['dpi'],
/*
'defaultFont' => 'sans-serif',
'margin_left' => 10,
'margin_right' => 10,
'margin_top' => 10,
'margin_bottom' => 10,
*/
]);
$fileName = get("title");
$document = pdf_html_content($documentInfo->html);
$path = "test";
$path = "$path/$fileName";
html_create($path, $document, $j['paper']);
yonlendir(url("storage/documents/$path.pdf"));
?>
@@ -0,0 +1,65 @@
@php
/**
* Get All Modules - Returns list of all enabled modules/types
*
* Used by Full Content Scanner to discover all translatable content
*
* Returns JSON:
* - success: boolean
* - modules: array of {slug, title}
*/
header('Content-Type: application/json');
use App\Types;
try {
// Get all enabled parent modules
$parentModules = Types::whereNull("kid")
->where("enabled", true)
->orderBy("s", "ASC")
->get(['slug', 'title']);
// Get all enabled child modules
$childModules = Types::whereNotNull("kid")
->where("enabled", true)
->orderBy("s", "ASC")
->get(['slug', 'title', 'kid']);
$modules = [];
// Add parent modules
foreach ($parentModules as $module) {
if (!empty($module->slug)) {
$modules[] = [
'slug' => $module->slug,
'title' => $module->title ?? $module->slug
];
}
}
// Add child modules
foreach ($childModules as $module) {
if (!empty($module->slug)) {
$modules[] = [
'slug' => $module->slug,
'title' => $module->title ?? $module->slug
];
}
}
echo json_encode([
'success' => true,
'modules' => $modules,
'total' => count($modules)
]);
} catch (\Exception $e) {
echo json_encode([
'success' => false,
'message' => 'Failed to load modules: ' . $e->getMessage(),
'modules' => []
]);
}
@endphp
@@ -0,0 +1,22 @@
<?php
/**
* @api-readonly
* Returns author information based on email
*/
if(isset($_SESSION['authors'][get("email")])) {
echo "-1";
} else {
$user = db("users")->select(
"prefix",
"name",
"surname",
"institution",
"orcid",
"country",
)->where("email",get("email"))->first();
echo json_encode_tr($user);
}
?>
@@ -0,0 +1,42 @@
<?php
/**
* @api-readonly
* Returns simple list of document folders
*/
// resources/views/admin-ajax/get-document-folders-simple.blade.php
$basePath = base_path('storage/documents');
function scanFolders($path, $relativePath = '') {
$items = [];
if (!is_dir($path)) {
return $items;
}
foreach (scandir($path) as $item) {
if ($item === '.' || $item === '..') continue;
$fullPath = $path . DIRECTORY_SEPARATOR . $item;
$itemRelativePath = $relativePath ? $relativePath . '/' . $item : $item;
if (is_dir($fullPath)) {
$pdfCount = count(glob($fullPath . '/*.pdf'));
$items[] = [
'text' => $item,
'path' => $itemRelativePath,
'pdf_count' => $pdfCount,
'children' => scanFolders($fullPath, $itemRelativePath)
];
}
}
usort($items, fn($a, $b) => strcmp($a['text'], $b['text']));
return $items;
}
echo json_encode([
'success' => true,
'folders' => scanFolders($basePath)
]);
@@ -0,0 +1,57 @@
<?php
/**
* @api-readonly
* Returns active dynamic document mappings
*/
// resources/views/admin-ajax/get-dynamic-documents.blade.php
use Illuminate\Support\Facades\DB;
// Set JSON header
header('Content-Type: application/json');
try {
// Get all active dynamic document mappings
$mappings = DB::table('register_document_mappings')
->where('is_active', 1)
->orderBy('order')
->orderBy('name')
->get();
$dynamicItems = [];
foreach ($mappings as $mapping) {
$displayTitle = !empty($mapping->description) ? $mapping->description : $mapping->name;
$dynamicItems[] = [
'id' => 'dynamic_' . $mapping->id,
'type' => 'dynamic',
'name' => $mapping->name,
'display_title' => $displayTitle,
'title2' => $mapping->name,
'path' => $mapping->search_folder,
'icon' => $mapping->icon ?? '🔧',
'badge_text' => $mapping->badge_text ?? 'Dynamic',
'badge_color' => $mapping->color ?? 'warning',
'sql_query' => $mapping->sql_query,
'identifier_field' => $mapping->identifier_field,
'date_field' => $mapping->date_field,
'file_search_pattern' => $mapping->file_search_pattern,
'title2_pattern' => $mapping->title2_pattern,
'title4_pattern' => $mapping->title4_pattern,
'is_dynamic' => true
];
}
echo json_encode([
'success' => true,
'dynamic_items' => $dynamicItems
], JSON_UNESCAPED_UNICODE);
} catch (\Throwable $th) {
echo json_encode([
'success' => false,
'message' => $th->getMessage()
], JSON_UNESCAPED_UNICODE);
}
exit;
@@ -0,0 +1,109 @@
<?php
/**
* @api-readonly
* Returns incoming control data for weld logs
*/
use App\Models\IncomingControl;
// Parametreleri al
$componentCode = request('component_code');
$lineCode = request('line_code');
$ruMaterialGroup = request('ru_group');
$weldingDate = request('welding_date');
$skip = (int) request('skip', 0);
$take = (int) request('take', 50);
// Response array
$response = [];
// Incoming Control verilerini getir
// Öncelikle element_code ile ara, eğer boşsa line_code (drawing_number) ile ara
// Hiçbir filtre yoksa veya filtre ile sonuç bulunamazsa tüm tabloyu göster
$query = IncomingControl::query();
$hasFilter = false;
if(!empty($componentCode)) {
// Önce component_code ile ara
$query->where('component_code', $componentCode);
$hasFilter = true;
} else if(!empty($lineCode)) {
// component_code boşsa, line_code ile drawing_number'a göre ara
$query->where('drawing_number', $lineCode);
$hasFilter = true;
}
// RU Material Group filtresi (opsiyonel)
if(!empty($ruMaterialGroup)) {
$ruGroups = explode(",", $ruMaterialGroup);
$materials = db("materials")->whereIn("ru_group", $ruGroups)->select("steel_grade")->get()->pluck("steel_grade")->toArray();
if(count($materials) > 0) {
$query = $query->whereIn("material", $materials);
}
}
// Total count for pagination
$totalCount = $query->count();
$filterFailed = false;
// Eğer filtre uygulandı ama sonuç bulunamadıysa, filtresiz tüm veriyi getir
if($hasFilter && $totalCount === 0) {
$query = IncomingControl::query();
$totalCount = $query->count();
$filterFailed = true; // Filtre uygulanamadı, tüm veri gösteriliyor
}
// Sıralama: En son girilen önce, sonra RFI tarihine göre
// Pagination uygula
$incomingData = $query
->orderBy('id', 'DESC') // En son girilen önce
->orderBy('rfi_date', 'ASC') // RFI tarihine göre sıralı
->skip($skip)
->take($take)
->get();
// Verileri formatla ve renklendirme flag'i ekle
foreach($incomingData as $item) {
$row = [
'id' => $item->id,
'component_code' => $item->component_code,
'rfi' => $item->rfi,
'rfi_date' => $item->rfi_date,
'description_en' => $item->description_en,
'description_ru' => $item->description_ru,
'project' => $item->project, // Zone olarak gösterilecek
'drawing_number' => $item->drawing_number,
'certificate_no' => $item->certificate_no,
'certificate_date' => $item->certificate_date,
'heat_number' => $item->heat_number,
'received_quantity' => $item->received_quantity,
'constructor' => $item->constructor,
'inspection_photo_file' => $item->inspection_photo_file,
'email_tq_file' => $item->email_tq_file,
'email_tq_number' => $item->email_tq_number,
'osd_defect_akt_file' => $item->osd_defect_akt_file,
'osd_report_date' => $item->osd_report_date,
'osd_report_no' => $item->osd_report_no,
];
// RFI date > welding_date kontrolü için flag
$row['highlight'] = false;
if(!empty($item->rfi_date) && !empty($weldingDate)) {
$rfiDate = strtotime($item->rfi_date);
$weldDate = strtotime($weldingDate);
if($rfiDate > $weldDate) {
$row['highlight'] = true;
}
}
$response[] = $row;
}
// JSON response döndür - pagination için data ve totalCount döndür
echo json_encode([
'data' => $response,
'totalCount' => $totalCount,
'filterFailed' => $filterFailed
]);
exit();
@@ -0,0 +1,85 @@
<?php
use App\Models\WeldLog;
use Illuminate\Support\Facades\DB;
// Helper function to sanitize input
$rfiNo = request('rfi_no');
$skip = (int) request('skip', 0);
$take = (int) request('take', 50);
// Response array
$response = [];
if (empty($rfiNo)) {
echo json_encode(['data' => [], 'totalCount' => 0]);
exit;
}
// Columns to search in WeldLog
$searchColumns = [
'joint_release_rfi_no',
'rt_release_rfi_no',
'ut_release_rfi_no',
'pt_release_rfi_no',
'mt_release_rfi_no',
'pmi_release_rfi_no',
'vt_release_rfi_no',
'pwht_release_rfi_no',
'ht_release_rfi_no',
'ferrite_release_rfi_no',
];
// Query Construction
$query = WeldLog::query();
$query->where(function($q) use ($searchColumns, $rfiNo) {
foreach ($searchColumns as $col) {
$q->orWhere($col, 'like', '%' . $rfiNo . '%'); // Using LIKE to catch exact matches or substrings if applicable, but RFI usually exact. matching exact is safer?
// User might want exact match. Let's try exact first?
// But get-rfi-for-release-log uses LIKE. "like %$rfiNo%".
// Let's stick to LIKE for flexibility.
}
});
$totalCount = $query->count();
$data = $query
->orderBy('id', 'DESC')
->skip($skip)
->take($take)
->get();
// Prepare response data
$resultData = [];
foreach ($data as $item) {
// Determine which type(s) matched (optional, but helpful)
$matchedTypes = [];
foreach ($searchColumns as $col) {
if (strpos($item->$col, $rfiNo) !== false) {
$matchedTypes[] = str_replace('_release_rfi_no', '', $col);
}
}
$resultData[] = [
'id' => $item->id,
'iso_number' => $item->iso_number,
'line_number' => $item->line_number,
'spool_number' => $item->spool_number,
'joint_no' => $item->no_of_the_joint_as_per_as_built_survey,
'type_of_welds' => $item->type_of_welds,
'type_of_joint' => $item->type_of_joint,
'welding_date' => $item->welding_date,
'matched_types' => implode(', ', $matchedTypes),
// Add all release RFI nos for reference
'joint_release' => $item->joint_release_rfi_no,
'rt_release' => $item->rt_release_rfi_no,
'ut_release' => $item->ut_release_rfi_no,
// ... add others if needed, or just rely on matched_types
];
}
echo json_encode([
'data' => $resultData,
'totalCount' => $totalCount
]);
?>
@@ -0,0 +1,28 @@
<?php
$slug = request('slug');
if (!$slug) {
echo json_encode(['status' => 'error', 'message' => 'Missing slug']);
exit;
}
$bladePath = resource_path("views/admin/type/{$slug}.blade.php");
$columns = [];
if (\Illuminate\Support\Facades\File::exists($bladePath)) {
$content = \Illuminate\Support\Facades\File::get($bladePath);
if (preg_match('/\$tableName\s*=\s*["\']([^"\']+)["\']\s*;/', $content, $matches)) {
$tableName = $matches[1];
try {
$columns = \Illuminate\Support\Facades\Schema::getColumnListing($tableName);
} catch (\Exception $e) {
$columns = [];
}
}
}
echo json_encode([
'status' => 'success',
'columns' => $columns
]);
?>
@@ -0,0 +1,8 @@
<?php $ncr_no = setting('ncr_no_pattern');
$counter = get_counter("ncr_no");
$ncr_no = str_replace("{number}", $counter, $ncr_no);
echo $ncr_no;
?>
@@ -0,0 +1,65 @@
<?php
use App\Models\RFI;
// Parametreleri al
$rfiNo = request('rfi_no');
$discipline = request('discipline');
$projectNo = request('project_no');
$skip = (int) request('skip', 0);
$take = (int) request('take', 50);
// Response array
$response = [];
// RFI verilerini getir
$query = RFI::query();
if(!empty($rfiNo)) {
$query->where('rfi_no', 'like', '%' . $rfiNo . '%');
}
if(!empty($discipline)) {
$query->where('discipline', $discipline);
}
if(!empty($projectNo)) {
$query->where('project_no', $projectNo);
}
// Total count for pagination
$totalCount = $query->count();
// Sıralama: En son girilen önce, sonra RFI tarihine göre
// Pagination uygula
$rfiData = $query
->orderBy('id', 'DESC') // En son girilen önce
->orderBy('inspection_date', 'ASC') // Inspection tarihine göre sıralı
->skip($skip)
->take($take)
->get();
// Verileri formatla
foreach($rfiData as $item) {
$row = [
'id' => $item->id,
'rfi_no' => $item->rfi_no,
'inspection_date' => $item->inspection_date,
'discipline' => $item->discipline,
'project_no' => $item->project_no,
'itp' => $item->itp,
'status' => $item->status,
'subcontractor' => $item->subcontractor,
'contractor' => $item->contractor,
'unit' => $item->unit,
'area' => $item->area,
'location' => $item->location,
'description' => $item->description,
];
$response[] = $row;
}
// JSON formatında yanıt döndür
echo json_encode($response);
?>
@@ -0,0 +1,8 @@
<?php $rfi_no = setting('rfi_no_pattern');
$counter = get_counter("rfi_no");
$rfi_no = str_replace("{number}", $counter, $rfi_no);
echo $rfi_no;
?>
@@ -0,0 +1,85 @@
<?php
use Google\Client as Google_Client;
use Google\Service\Sheets as Google_Service_Sheets;
use Google\Service\Drive as Google_Service_Drive;
function getClientWithCredentials() {
$client = new Google_Client();
$client->setApplicationName('Google Sheets API PHP Quickstart');
$client->setScopes([Google_Service_Sheets::SPREADSHEETS, Google_Service_Drive::DRIVE]);
$client->setAuthConfig("stellar-430709-1e97a08bdfd7.json");
$client->setAccessType('offline');
$client->setAccessToken("AIzaSyAAAkIgkUQPicl9MkAbBNmBImM2pD19KFU");
if ($client->isAccessTokenExpired()) {
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
}
return $client;
}
$client = getClientWithCredentials();
dd($client);
$service = new Google_Service_Sheets($client);
$spreadsheetId = '11McnNecoafCA-56qLJzODY3H8mx5LC89GKbfWSTiY_4';
$range = 'Sheet1!A1:E'; // Örnek aralık
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
$htmlContent = ''; // HTML içeriği burada oluşturulacak
foreach ($values as $row) {
$htmlContent .= implode(' ', $row) . '<br>';
}
$placeholders = ['{joker_alan}'];
$replacements = ['gerçek_değer'];
$updatedContent = str_replace($placeholders, $replacements, $htmlContent);
$range = 'Sheet1!A1'; // Başlangıç hücresi
$values = [
[$updatedContent] // Tek hücrede tüm HTML içeriği
];
$body = new Google_Service_Sheets_ValueRange([
'values' => $values
]);
$params = [
'valueInputOption' => 'RAW'
];
$service->spreadsheets_values->update($spreadsheetId, $range, $body, $params);
$driveService = new Google_Service_Drive($client);
$fileId = $spreadsheetId;
$response = $driveService->files->export($fileId, 'application/pdf', array(
'alt' => 'media'
));
$filePath = 'path/to/save/yourfile.pdf';
file_put_contents($filePath, $response->getBody()->getContents());
use Illuminate\Support\Facades\Storage;
Storage::put('public/pdfs/yourfile.pdf', file_get_contents($filePath));
?>
@@ -0,0 +1,282 @@
<?php
/**
* @api-readonly
* Returns handover status dashboard data
*/
use Illuminate\Support\Facades\DB;
// Controller sayısını ayardan al
$controlCount = setting('handover_control_count', 3);
// Initialize response
$response = [];
// Tüm handovers kayıtlarını çek
$selectFields = array_merge(
[
'created_date',
'object',
'responsible',
'atg_date',
'final_status'
],
// Tüm controller'lar için date alanları
array_reduce(range(1, $controlCount), function($carry, $i) {
$carry[] = "control{$i}_date1";
$carry[] = "control{$i}_date2";
$carry[] = "control{$i}_date3";
return $carry;
}, []),
// Tüm controller'lar için status alanları
array_map(function ($i) {
return "control{$i}_id_status";
}, range(1, $controlCount))
);
$handovers = DB::table('handovers')->select($selectFields)->get();
// ----------------------------------------------------------------
// 1) EXISTING LOGIC: Hand-over Status (Object/Controller Table)
// ----------------------------------------------------------------
// 1) TABLO DATASI: object bazında grupla
$objectGroups = [];
foreach ($handovers as $row) {
$object = $row->object;
if (!$object)
continue; // Skip empty objects
if (!isset($objectGroups[$object])) {
$objectGroups[$object] = [
'object' => $object,
'total' => 0,
'waiting' => 0,
'archive' => 0
];
for ($i = 1; $i <= $controlCount; $i++) {
$objectGroups[$object]["controller{$i}_accept"] = 0;
$objectGroups[$object]["controller{$i}_pending"] = 0;
}
}
$objectGroups[$object]['total']++;
// Waiting durumu: created_date yoksa veya final_status = 'Waiting' ise
if (!$row->created_date || $row->final_status === 'Waiting') {
$objectGroups[$object]['waiting']++;
}
// Archive durumu: final_status = 'Archive' veya archive alanı dolu ise
if ($row->final_status === 'Archive' || ($row->atg_date && $row->final_status !== 'Waiting')) {
$objectGroups[$object]['archive']++;
}
for ($i = 1; $i <= $controlCount; $i++) {
$status = $row->{"control{$i}_id_status"};
if ($status === 'Agreed / подписано') {
$objectGroups[$object]["controller{$i}_accept"]++;
} else {
$objectGroups[$object]["controller{$i}_pending"]++;
}
}
}
$tableData = array_values($objectGroups);
// 2) CHART DATASI: haftalık object bazında sayım
$objectData = [];
foreach ($handovers as $row) {
if (!$row->created_date)
continue;
$object = $row->object ?: 'Unknown';
$createdDate = $row->created_date;
if (!isset($objectData[$object])) {
$objectData[$object] = [
'created_date' => $createdDate,
'controllers' => []
];
}
for ($i = 1; $i <= $controlCount; $i++) {
$status = $row->{"control{$i}_id_status"};
if ($status === 'Agreed / подписано') {
$objectData[$object]['controllers'][$i] = true;
}
}
}
$weekObjectCounts = [];
foreach ($objectData as $object => $data) {
$hasAccept = !empty($data['controllers']);
if ($hasAccept && $data['created_date']) {
try {
$dt = new DateTime($data['created_date']);
$week = $dt->format('o-W');
if (!isset($weekObjectCounts[$week])) {
$weekObjectCounts[$week] = ['week' => $week, 'objects' => []];
}
$weekObjectCounts[$week]['objects'][$object] = true;
} catch (\Exception $e) {
}
}
}
$chartData = [];
foreach ($weekObjectCounts as $week => $weekData) {
$chartData[] = [
'week' => $week,
'accepted_objects' => count($weekData['objects'])
];
}
usort($chartData, function ($a, $b) {
return strcmp($a['week'], $b['week']);
});
$response['tableData'] = $tableData;
$response['chartData'] = $chartData;
// ----------------------------------------------------------------
// 2) NEW DASHBOARD LOGIC (Merged)
// ----------------------------------------------------------------
// Initialize containers
$weeklyCreatedMap = [];
$weeklyPersonnelMap = [];
$weeklyArchivedMap = [];
$monthlyWaitMap = []; // Format: ['Y-m' => ['control1_sum' => days, 'control2_sum' => days, ...]]
foreach ($handovers as $row) {
// A. Weekly Created
if ($row->created_date) {
try {
$dt = new DateTime($row->created_date);
$yearWeek = $dt->format('o-W');
// Store date of week start for better labels if needed, or just year-week
// To match previous logic: format as Y-m-d start of week
$dto = new DateTime();
$dto->setISODate($dt->format('o'), $dt->format('W'));
$weekStart = $dto->format('Y-m-d');
if (!isset($weeklyCreatedMap[$weekStart]))
$weeklyCreatedMap[$weekStart] = 0;
$weeklyCreatedMap[$weekStart]++;
// B. Weekly Personnel
if ($row->responsible) {
$key = $weekStart . '_' . $row->responsible;
if (!isset($weeklyPersonnelMap[$key])) {
$weeklyPersonnelMap[$key] = [
'week' => $weekStart,
'responsible' => $row->responsible,
'count' => 0
];
}
$weeklyPersonnelMap[$key]['count']++;
}
} catch (\Exception $e) {
}
}
// C. Weekly Archived (using atg_date or final_status = 'Archive')
// Archive tarihi: atg_date varsa onu kullan, yoksa created_date kullan (final_status = 'Archive' ise)
$archiveDate = null;
if ($row->atg_date) {
$archiveDate = $row->atg_date;
} elseif ($row->final_status === 'Archive' && $row->created_date) {
$archiveDate = $row->created_date;
}
if ($archiveDate) {
try {
$dt = new DateTime($archiveDate);
$dto = new DateTime();
$dto->setISODate($dt->format('o'), $dt->format('W'));
$weekStart = $dto->format('Y-m-d');
if (!isset($weeklyArchivedMap[$weekStart]))
$weeklyArchivedMap[$weekStart] = 0;
$weeklyArchivedMap[$weekStart]++;
} catch (\Exception $e) {
}
}
// D. Wait Time Analysis - Tüm Controller'lar için
// Her control için: Date 2 - Date 1 (toplam bekleme süresi)
for ($i = 1; $i <= $controlCount; $i++) {
$date1Field = "control{$i}_date1";
$date2Field = "control{$i}_date2";
if (isset($row->$date1Field) && isset($row->$date2Field) && $row->$date1Field && $row->$date2Field) {
try {
$d1 = new DateTime($row->$date1Field);
$d2 = new DateTime($row->$date2Field);
if ($d2 > $d1) {
$month = $d1->format('Y-m');
$waitDays = $d1->diff($d2)->days;
if (!isset($monthlyWaitMap[$month])) {
$monthlyWaitMap[$month] = [];
for ($j = 1; $j <= $controlCount; $j++) {
$monthlyWaitMap[$month]["control{$j}_sum"] = 0;
}
}
$monthlyWaitMap[$month]["control{$i}_sum"] += $waitDays;
}
} catch (\Exception $e) {
// Skip invalid dates
}
}
}
}
// Format Dashboard Data
// 1. Weekly Created
$weeklyCreatedData = [];
foreach ($weeklyCreatedMap as $week => $count) {
$weeklyCreatedData[] = ['week' => $week, 'count' => $count];
}
usort($weeklyCreatedData, function ($a, $b) {
return strcmp($a['week'], $b['week']); });
$response['weeklyCreated'] = $weeklyCreatedData;
// 2. Weekly Personnel
$weeklyPersonnelData = array_values($weeklyPersonnelMap);
usort($weeklyPersonnelData, function ($a, $b) {
return strcmp($a['week'], $b['week']); });
$response['weeklyPersonnel'] = $weeklyPersonnelData;
// 3. Weekly Archived
$weeklyArchivedData = [];
foreach ($weeklyArchivedMap as $week => $count) {
$weeklyArchivedData[] = ['week' => $week, 'count' => $count];
}
usort($weeklyArchivedData, function ($a, $b) {
return strcmp($a['week'], $b['week']); });
$response['weeklyArchived'] = $weeklyArchivedData;
// 4. Wait Data - Tüm Controller'lar için toplam bekleme süresi
$waitData = [];
foreach ($monthlyWaitMap as $month => $data) {
$item = ['month' => $month];
// Her control için toplam bekleme süresi (gün cinsinden)
for ($i = 1; $i <= $controlCount; $i++) {
$key = "control{$i}_sum";
$item["control{$i}"] = isset($data[$key]) ? round($data[$key], 1) : 0;
}
$waitData[] = $item;
}
usort($waitData, function ($a, $b) {
return strcmp($a['month'], $b['month']); });
$response['waitData'] = $waitData;
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
?>
@@ -0,0 +1,45 @@
<?php
function getHtmlFiles($dir) {
$htmlFiles = [];
if (!is_dir($dir)) {
return $htmlFiles;
}
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
foreach ($iterator as $file) {
if ($file->isDir()) continue; // Dizinleri atla
$fileName = $file->getFilename();
if (pathinfo($fileName, PATHINFO_EXTENSION) === 'html') {
$htmlFiles[] = $file->getPathname();
}
}
return $htmlFiles;
}
$folderName = get("path");
$pdfFolderName = "$folderName-PDF";
$htmlDirectory = "$folderName/";
$pdfDirectory = "$pdfFolderName/";
$htmlFiles = getHtmlFiles($htmlDirectory);
foreach($htmlFiles AS $htmlFile) {
$pdfFile = str_replace($folderName, $pdfFolderName, $htmlFile);
$pdfFile = str_replace(".html", ".pdf", $pdfFile);
$pdfDirName = dirname($pdfFile);
//dump($pdfFile);
//dump($htmlFile);
@mkdir($pdfDirName, 0777, true);
(html_to_pdf(
$htmlFile,
$pdfFile,
get("paper")
));
}
?>
@include("admin-ajax.create-zip-file")
@@ -0,0 +1,35 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
//print_r( $request->all());
$post = $request->all();
/*
Array ( [table] => contents [value] => Başlık buraya [_token] => yVfSAMNxOD6rdtIeLkZllFvm46a1TAgPtbO1fJHu [id] => 62 [name] => name )
*/
if(!isset($post['key'])) {
$post['key'] = "id";
}
DB::table($post['table'])
->where($post['key'], $post['id'])
->update([
$post['name'] => $post['value'],
'updated_at' => simdi(),
]);
$return = back();
echo "ok";
@@ -0,0 +1,613 @@
<?php
/**
* Inspection History - Row level photo and comment upload
*/
use App\Models\InspectionHistory;
use App\Models\User;
// Add Magnific Popup assets
?>
<link rel="stylesheet" href="<?php echo asset('assets/admin/js/plugins/magnific-popup/magnific-popup.css'); ?>">
<?php
$rowId = get("row_id");
$table = get("table");
$moduleSlug = get("module_slug");
// Get settings configuration if module_slug provided
$inspectionConfig = null;
$inspectionHistoryPath = null;
$inspectionHistoryFileNamePattern = null;
if ($moduleSlug) {
$inspectionConfig = getInspectionHistoryConfig($moduleSlug);
if ($inspectionConfig) {
$inspectionHistoryPath = $inspectionConfig['path'] ?? null;
$inspectionHistoryFileNamePattern = $inspectionConfig['pattern'] ?? null;
}
}
// Get inspection history records for this specific row
$users = User::all();
$historyRecords = InspectionHistory::where('table_name', $table)
->where('record_id', $rowId)
->orderBy('created_at', 'DESC')
->get();
// Convert history records to JSON for DataGrid
$historyJson = json_encode($historyRecords);
// Convert users to a lookup object for DataGrid
$usersLookup = [];
foreach ($users as $user) {
$usersLookup[$user->id] = $user->name;
}
$usersJson = json_encode($usersLookup);
?>
<div class="card mb-3">
<div class="card-header">
<h5>
<span class="badge badge-primary">{{e2($table)}}</span> /
<span class="badge badge-secondary">Row #{{e2($rowId)}}</span>
<span class="badge badge-default">{{e2("Inspection History")}}</span>
</h5>
</div>
<div class="card-body">
<?php if ($inspectionHistoryFileNamePattern): ?>
<div class="alert alert-info mb-3">
<strong>{{e2("File Name Pattern")}}:</strong> {{$inspectionHistoryFileNamePattern}}
<br><small>{{e2("Files will be named using this pattern with column values from the row")}}</small>
</div>
<?php endif; ?>
<form id="inspectionHistoryForm" method="post" enctype="multipart/form-data">
@csrf
<input type="hidden" name="table_name" value="<?php echo $table; ?>">
<input type="hidden" name="record_id" value="<?php echo $rowId; ?>">
<?php if ($moduleSlug): ?>
<input type="hidden" name="module_slug" value="<?php echo $moduleSlug; ?>">
<?php endif; ?>
<?php if ($inspectionHistoryFileNamePattern): ?>
<input type="hidden" name="file_name_pattern" value="<?php echo htmlspecialchars($inspectionHistoryFileNamePattern); ?>">
<?php endif; ?>
<div class="form-group">
<label for="comment">{{e2("Comment")}} <span class="text-danger">*</span></label>
<textarea class="form-control" id="comment" name="comment" rows="3" required></textarea>
<small class="form-text text-muted">{{e2("Comment is required")}}</small>
</div>
<div class="form-group">
<label for="photo">{{e2("Photo")}} <span class="text-muted">({{e2("Optional")}})</span></label>
<input type="file" class="form-control-file" id="photo" name="photo[]" accept="image/*" multiple>
<small class="form-text text-muted">{{e2("Allowed formats: JPG, JPEG, PNG, GIF, WEBP. Max size: 20MB")}}</small>
<div id="photoPreview" class="mt-2" style="display: none; flex-wrap: wrap; gap: 10px;">
<!-- Preview images will be appended here -->
</div>
</div>
<button type="submit" class="btn btn-primary">
<i class="fa fa-upload"></i> {{e2("Upload Inspection History")}}
</button>
</form>
</div>
</div>
<div class="card fullsize-grid">
<div class="card-header">
<h5>{{e2("Inspection History Records")}}</h5>
</div>
<div class="card-body p-0">
<!-- DevExtreme DataGrid container -->
<div id="inspectionHistoryDataGrid" style="width: 100%;"></div>
</div>
</div>
<style>
/* DataGrid için stil ayarları */
.dx-datagrid {
min-height: 500px;
}
/* Card gövdesi padding kaldırma */
.card-body.p-0 {
padding: 0 !important;
}
/* Card kendisi için margin ayarları */
.card.fullsize-grid {
margin-bottom: 0 !important;
}
.photo-thumbnail {
max-width: 100px;
max-height: 100px;
cursor: pointer;
border: 1px solid #ddd;
border-radius: 4px;
padding: 5px;
}
.photo-thumbnail:hover {
border-color: #007bff;
}
/* Override Magnific Popup z-index to show above modals */
.mfp-bg, .mfp-wrap {
z-index: 2000 !important;
}
</style>
<script src="<?php echo asset('assets/admin/js/plugins/magnific-popup/jquery.magnific-popup.min.js'); ?>"></script>
<script>
$(function() {
// Users lookup table from server
const usersLookup = <?php echo $usersJson; ?>;
// Format user information
function formatUser(userId) {
return usersLookup[userId] || 'Unknown';
}
// Format file size
function formatFileSize(bytes) {
if (!bytes) return '';
if (bytes < 1024) return bytes + ' B';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
}
// Calculate grid height - responsive approach
function calculateGridHeight() {
return Math.max(500, window.innerHeight * 0.7);
}
// Initialize DataGrid with history records
const historyRecords = <?php echo $historyJson; ?>;
const dataGrid = $("#inspectionHistoryDataGrid").dxDataGrid({
dataSource: historyRecords,
keyExpr: "id",
showBorders: true,
height: calculateGridHeight(),
width: "100%",
selection: {
mode: "multiple",
showCheckBoxesMode: "always"
},
filterRow: {
visible: true,
applyFilter: "auto"
},
searchPanel: {
visible: true,
width: 240,
placeholder: "{{e2('Search...')}}"
},
headerFilter: {
visible: true
},
grouping: {
autoExpandAll: false
},
paging: {
pageSize: 10
},
pager: {
showPageSizeSelector: true,
allowedPageSizes: [5, 10, 20, 50],
showInfo: true
},
columnAutoWidth: true,
columns: [
{
dataField: "created_at",
caption: "{{e2('Date')}}",
dataType: "datetime",
format: "dd.MM.yyyy HH:mm",
sortOrder: "desc",
width: 160
},
{
dataField: "comment",
caption: "{{e2('Comment')}}",
dataType: "string",
width: 300
},
{
dataField: "file_path",
caption: "{{e2('Photo')}}",
dataType: "string",
width: 150,
cellTemplate: function(container, options) {
if (options.value) {
// Build correct photo URL - file_path is in format: documents/path/to/file.jpg
let photoUrl;
if (options.value.startsWith('storage/')) {
photoUrl = '<?php echo url(""); ?>' + '/' + options.value;
} else if (options.value.startsWith('documents/')) {
photoUrl = '<?php echo url("storage"); ?>' + '/' + options.value;
} else {
photoUrl = '<?php echo url("storage/documents"); ?>' + '/' + options.value;
}
// Create download URL
const downloadUrl = photoUrl;
// Create link for lightbox
const link = $('<a>')
.attr('href', photoUrl)
.addClass('image-popup-vertical-fit')
.attr('data-download-url', downloadUrl)
.attr('title', options.data.file_name || '{{e2("Photo")}}');
const img = $('<img>')
.attr('src', photoUrl)
.attr('alt', '{{e2("Photo")}}')
.addClass('photo-thumbnail');
link.append(img);
container.append(link);
} else {
container.append('<span class="text-muted">-</span>');
}
}
},
{
dataField: "file_name",
caption: "{{e2('File Name')}}",
dataType: "string",
width: 200
},
{
dataField: "file_size",
caption: "{{e2('File Size')}}",
dataType: "number",
width: 100,
cellTemplate: function(container, options) {
container.append(formatFileSize(options.value));
}
},
{
dataField: "user_id",
caption: "{{e2('User')}}",
lookup: {
dataSource: Object.entries(usersLookup).map(([id, name]) => ({ id: parseInt(id), name: name })),
displayExpr: "name",
valueExpr: "id"
},
width: 150
},
{
dataField: "ip_address",
caption: "{{e2('IP Address')}}",
dataType: "string",
width: 120
},
{
type: "buttons",
width: 120,
buttons: [
{
hint: "{{e2('Download')}}",
icon: "download",
visible: function(e) {
return !!e.row.data.file_path;
},
onClick: function(e) {
const filePath = e.row.data.file_path;
let downloadUrl;
if (filePath.startsWith('storage/')) {
downloadUrl = '<?php echo url(""); ?>' + '/' + filePath;
} else if (filePath.startsWith('documents/')) {
downloadUrl = '<?php echo url("storage"); ?>' + '/' + filePath;
} else {
downloadUrl = '<?php echo url("storage/documents"); ?>' + '/' + filePath;
}
const link = document.createElement('a');
link.href = downloadUrl;
link.download = e.row.data.file_name || 'download';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
},
<?php if(isAuth($moduleSlug ?? $table, 'full_control')): ?>
{
hint: "{{e2('Delete')}}",
icon: "trash",
onClick: function(e) {
Swal.fire({
title: '{{e2("Are you sure?")}}',
text: '{{e2("You won't be able to revert this!")}}',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: '{{e2("Yes, delete it!")}}'
}).then((result) => {
if (result.isConfirmed) {
deleteInspectionHistory(e.row.data.id);
}
});
}
}
<?php endif; ?>
]
}
],
export: {
enabled: true,
allowExportSelectedData: true
},
onToolbarPreparing: function(e) {
<?php if(isAuth($moduleSlug ?? $table, 'full_control')): ?>
e.toolbarOptions.items.unshift({
location: "after",
widget: "dxButton",
options: {
icon: "trash",
text: "{{e2('Delete Selected')}}",
type: "danger",
stylingMode: "text",
hint: "{{e2('Delete selected records')}}",
onClick: function() {
const selectedRows = dataGrid.getSelectedRowKeys();
if (selectedRows.length === 0) {
Swal.fire({
icon: 'info',
title: '{{e2("Info")}}',
text: '{{e2("Please select at least one record to delete.")}}'
});
return;
}
Swal.fire({
title: '{{e2("Are you sure?")}}',
text: '{{e2("You are about to delete")}} ' + selectedRows.length + ' {{e2("records. You cannot revert this!")}}',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: '{{e2("Yes, delete them!")}}'
}).then((result) => {
if (result.isConfirmed) {
bulkDeleteInspectionHistory(selectedRows);
}
});
}
}
});
<?php endif; ?>
},
onContentReady: function(e) {
if(historyRecords.length === 0) {
e.component.option("noDataText", "{{e2('No inspection history found for this row')}}");
}
// Initialize Magnific Popup on cached/rendered elements
// We use delegation on the datagrid container
$('#inspectionHistoryDataGrid').magnificPopup({
delegate: 'a.image-popup-vertical-fit',
type: 'image',
closeOnContentClick: true,
mainClass: 'mfp-img-mobile',
image: {
verticalFit: true,
titleSrc: function(item) {
const title = item.el.attr('title');
const downloadUrl = item.el.attr('data-download-url');
return title + ' &nbsp; <a href="' + downloadUrl + '" download class="btn btn-xs btn-primary" style="padding: 2px 5px; font-size: 10px; color: white;"><i class="fa fa-download"></i> {{e2("Download")}}</a>';
}
},
gallery: {
enabled: true
}
});
}
}).dxDataGrid("instance");
// Window resize handler
$(window).on("resize", function() {
dataGrid.option("height", calculateGridHeight());
});
// Photo preview
$('#photo').on('change', function(e) {
const files = e.target.files;
const previewContainer = $('#photoPreview');
previewContainer.empty(); // Clear existing previews
if (files && files.length > 0) {
previewContainer.css('display', 'flex');
Array.from(files).forEach(file => {
if (!file.type.startsWith('image/')) return;
const reader = new FileReader();
reader.onload = function(e) {
const img = $('<img>')
.attr('src', e.target.result)
.addClass('img-thumbnail')
.css({
'max-width': '150px',
'max-height': '150px',
'object-fit': 'cover'
});
previewContainer.append(img);
};
reader.readAsDataURL(file);
});
} else {
previewContainer.hide();
}
});
// Form submission handler
$('#inspectionHistoryForm').submit(function(e) {
e.preventDefault();
const formData = new FormData(this);
// Show loading state
Swal.fire({
title: '{{e2("Uploading...")}}',
text: '{{e2("Please wait while your files are being uploaded.")}}',
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
showConfirmButton: false,
didOpen: () => {
Swal.showLoading();
}
});
$.ajax({
url: '<?php echo url('ajax/inspection-history/upload'); ?>',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
if(response.success) {
Swal.fire({
icon: 'success',
title: '{{e2("Success!")}}',
text: '{{e2("Inspection history has been saved successfully.")}}',
confirmButtonText: 'OK'
}).then((result) => {
refreshHistory();
// Clear form
$('#inspectionHistoryForm')[0].reset();
$('#photoPreview').hide();
});
} else {
Swal.fire({
icon: 'error',
title: '{{e2("Error!")}}',
text: response.message || '{{e2("Failed to save inspection history.")}}',
confirmButtonText: 'OK'
});
}
},
error: function(xhr) {
let errorMessage = '{{e2("An error occurred while processing your request.")}}';
if (xhr.responseJSON && xhr.responseJSON.message) {
errorMessage = xhr.responseJSON.message;
}
Swal.fire({
icon: 'error',
title: '{{e2("Error!")}}',
text: errorMessage,
confirmButtonText: 'OK'
});
}
});
});
// Function to refresh history
function refreshHistory() {
$.ajax({
url: '<?php echo url('ajax/inspection-history/list'); ?>',
type: 'GET',
data: {
table_name: '<?php echo $table; ?>',
record_id: <?php echo $rowId; ?>
},
success: function(response) {
if (Array.isArray(response)) {
dataGrid.option('dataSource', response);
} else {
console.error('Invalid response format:', response);
}
},
error: function() {
Swal.fire('{{e2("Error")}}', '{{e2("Failed to refresh inspection history.")}}', 'error');
}
});
}
// Function to delete inspection history
function deleteInspectionHistory(id) {
$.ajax({
url: '<?php echo url('ajax/inspection-history/delete'); ?>/' + id,
type: 'DELETE',
data: {
_token: '<?php echo csrf_token(); ?>'
},
success: function(response) {
if(response.success) {
Swal.fire({
icon: 'success',
title: '{{e2("Deleted!")}}',
text: '{{e2("Inspection history has been deleted.")}}',
confirmButtonText: 'OK'
}).then(() => {
refreshHistory();
});
} else {
Swal.fire({
icon: 'error',
title: '{{e2("Error!")}}',
text: response.message || '{{e2("Failed to delete inspection history.")}}',
confirmButtonText: 'OK'
});
}
},
error: function(xhr) {
Swal.fire({
icon: 'error',
title: '{{e2("Error!")}}',
text: '{{e2("An error occurred while deleting.")}}',
confirmButtonText: 'OK'
});
}
});
}
// Function to bulk delete inspection history
function bulkDeleteInspectionHistory(ids) {
$.ajax({
url: '<?php echo url('ajax/inspection-history/bulk-delete'); ?>',
type: 'POST',
data: {
_token: '<?php echo csrf_token(); ?>',
ids: ids
},
success: function(response) {
if(response.success) {
Swal.fire({
icon: 'success',
title: '{{e2("Deleted!")}}',
text: response.message || '{{e2("Selected records have been deleted.")}}',
confirmButtonText: 'OK'
}).then(() => {
refreshHistory();
// Clear selection
dataGrid.clearSelection();
});
} else {
Swal.fire({
icon: 'error',
title: '{{e2("Error!")}}',
text: response.message || '{{e2("Failed to delete selected records.")}}',
confirmButtonText: 'OK'
});
}
},
error: function(xhr) {
Swal.fire({
icon: 'error',
title: '{{e2("Error!")}}',
text: '{{e2("An error occurred while deleting.")}}',
confirmButtonText: 'OK'
});
}
});
}
});
</script>
@@ -0,0 +1,11 @@
<?php
$query = db("welder_tests")
->where("id", "!=", get("id"))
->where("kss_number", get("value"))
->count();
if($query>0) {
echo 0;
} else {
echo 1;
}
?>
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
//bir dil dosyasına ait tüm içerikleri json işlemini yapar.
$p = $request->all();
$dizi = array();
$contents = Contents::get();
$k=0;
@@ -0,0 +1,34 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contents;
use Illuminate\Support\Facades\DB;
//bir dil dosyasını günceller
$p = $request->all();
$dizi = array();
foreach($p AS $alan => $deger) {
if(validBase64($alan)) {
$alan2 = base64_decode($alan);
$dizi[$alan2] = $deger;
}
@@ -0,0 +1 @@
<?php yonlendir(url(get("path") . "?" . rand())); ?>
@@ -0,0 +1,16 @@
<?php
$u = u();
if(isAdmin($u)){
// Mevcut oturumu tamamen temizle
Auth::logout();
// Kullanıcı cache'ini temizle
Session::forget('cached_user');
// Yeni kullanıcı ile giriş yap
Auth::loginUsingId(get("id"));
// Session'ı yenile
session()->regenerate();
}
?>
@@ -0,0 +1,179 @@
<?php
// CSRF token kontrolü
if (!isset($_POST['_token']) && !isset($_GET['_token'])) {
echo json_encode(['status' => 'error', 'message' => 'CSRF token gerekli']);
exit;
}
// Güncelleme işlemi
if (isset($_GET['update']) || isset($_POST['update'])) {
$tableName = $_POST['table'] ?? $_GET['table'] ?? '';
$id = $_POST['id'] ?? $_GET['id'] ?? '';
$columnName = $_POST['column'] ?? $_GET['column'] ?? '';
$newValue = $_POST['value'] ?? $_GET['value'] ?? '';
if (empty($tableName) || empty($id) || empty($columnName)) {
echo json_encode(['status' => 'error', 'message' => 'Missing parameters']);
exit;
}
try {
// Veritabanı güncelleme
$result = db($tableName)->where('id', $id)->update([$columnName => $newValue]);
if ($result) {
echo json_encode(['status' => 'success', 'message' => 'Update successful']);
} else {
echo json_encode(['status' => 'error', 'message' => 'Update failed']);
}
} catch (Exception $e) {
echo json_encode(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
}
exit;
}
// Görüntüleme işlemi
$tableName = $_GET['table'] ?? '';
$id = $_GET['id'] ?? '';
$columnName = $_GET['column'] ?? '';
if (empty($tableName) || empty($id) || empty($columnName)) {
echo '<div class="alert alert-danger">Missing parameters: table=' . htmlspecialchars($tableName) . ', id=' . htmlspecialchars($id) . ', column=' . htmlspecialchars($columnName) . '</div>';
exit;
}
// Get current data
$currentData = db($tableName)->where('id', $id)->first();
$currentValue = $currentData->{$columnName} ?? '';
// Get column information
?>
<div class="modal-header">
<h5 class="modal-title">Edit {{ e2($columnName) }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="longTextEditForm">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="table" value="{{ $tableName }}">
<input type="hidden" name="id" value="{{ $id }}">
<input type="hidden" name="column" value="{{ $columnName }}">
<input type="hidden" name="update" value="1">
<div class="form-group">
<label for="longTextValue">{{ e2($columnName) }}</label>
<textarea
class="form-control"
id="longTextValue"
name="value"
rows="10"
style="min-height: 200px;"
placeholder="Enter {{ e2($columnName) }}..."
>{{ $currentValue }}</textarea>
</div>
</form>
</div>
<div class="text-center">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" onclick="saveLongText()">Save</button>
</div>
<script>
$(".modal-footer").hide();
function saveLongText() {
var formData = new FormData(document.getElementById('longTextEditForm'));
$.ajax({
url: '{{ url("admin-ajax/long-text-edit") }}',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
try {
var result = JSON.parse(response);
if (result.status === 'success') {
// Successful update
Swal.fire({
icon: 'success',
title: 'Success',
text: result.message,
timer: 2000,
showConfirmButton: false
});
// Close modal
$('#modal-popin').modal('hide');
// Refresh DataGrid - safe approach
try {
// Check if dataGrid element exists
if ($("#dataGrid").length > 0) {
// Try to get DevExtreme instance and refresh
var gridElement = $("#dataGrid");
if (gridElement.hasClass("dx-datagrid")) {
// Element is already a DevExtreme DataGrid
gridElement.dxDataGrid("refresh");
} else {
// Try to get instance and refresh
var instance = gridElement.dxDataGrid("instance");
if (instance && typeof instance.refresh === 'function') {
instance.refresh();
} else {
// Fallback: reload page
location.reload();
}
}
} else {
// DataGrid not found, reload page
location.reload();
}
} catch (error) {
console.log("DataGrid refresh error:", error);
// Final fallback: reload page
location.reload();
}
} else {
Swal.fire({
icon: 'error',
title: 'Error',
text: result.message
});
}
} catch (e) {
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Error processing response'
});
}
},
error: function(xhr, status, error) {
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Error during update: ' + error
});
}
});
}
// Textarea auto-resize
$(document).ready(function() {
var textarea = document.getElementById('longTextValue');
textarea.addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = Math.max(200, this.scrollHeight) + 'px';
});
// Save with Enter key (Ctrl+Enter)
textarea.addEventListener('keydown', function(e) {
if (e.ctrlKey && e.key === 'Enter') {
saveLongText();
}
});
});
</script>
@@ -0,0 +1,50 @@
<?php
//print_r($_POST);
$c = (Array) $manuscript;
$j = json_decode($c['json'],true);
$u = (Array) $user;
$url = env("APP_URL");
$html = post("html");
$html = str_replace("{prefix}",$u['prefix'],$html);
$html = str_replace("{name}",$u['name'],$html);
$html = str_replace("{email}",$u['email'],$html);
$html = str_replace("{surname}",$u['surname'],$html);
$html = str_replace("{institution}",$u['institution'],$html);
$html = str_replace("{country}",$u['country'],$html);
$html = str_replace("{id}",$c['slug'],$html);
$html = str_replace("{title}",$c['title'],$html);
$html = str_replace("{file}","<a href='$url/{$c['files']}'>$url/{$c['files']}</a>",$html);
$html = str_replace("{abstract}",$j['html'],$html);
$title = str_replace("{id}",$c['slug'],post("title"));
$title = str_replace("{email}",$u['email'],$title);
// e($html);
$mailler = explode(",",$_POST['to']);
$maillercc = explode(",",$_POST['cc']);
//$mailler = array_merge($mailler,$maillercc);
$ccdizi = array();
foreach($maillercc AS $cc) {
if($cc!=$_POST['to']) {
array_push($ccdizi,$cc);
}
}
$ccdizi = implode(",",$ccdizi);
foreach($mailler AS $m) {
$m = trim($m);
e("$m <br />");
echo mailSend($m,$title,$html,$ccdizi);
mailSend(env("MAIL_USERNAME"),$title,$html);
}
$alert = "{$_POST['to']} Delivered to e-mail addresses";
if(!postesit("cc","")) {
$alert = "{$_POST['to']},{$_POST['cc']},{$_POST['bcc']} Delivered to e-mail addresses";
}
bilgi($alert);
exit();
?>
@@ -0,0 +1,117 @@
<?php
$template = db("mail_templates")->where("id",get("id"))->first();
$manuscript = db("manuscripts")->where("id",get("mid"))->first();
$user = u2($manuscript->uid);
//dump($user);
$json = j($manuscript->json);
if(getisset("send")) {
?>
@include("admin-ajax.mail-send")
<?php
}
$authors = $json['authors'];
//dump($json);
//dump($template);
/*
$html = str_replace("{prefix}",$u['prefix'],$html);
$html = str_replace("{adi}",$u['name'],$html);
$html = str_replace("{email}",$u['email'],$html);
$html = str_replace("{surname}",$u['surname'],$html);
$html = str_replace("{institution}",$u['institution'],$html);
$html = str_replace("{country}",$u['country'],$html);
$html = str_replace("{id}",$c['slug'],$html);
$html = str_replace("{title}",$c['title'],$html);
$html = str_replace("{file}","<a href='$url/{$c['files']}'>$url/{$c['files']}</a>",$html);
$html = str_replace("{abstract}",$j['html'],$html);
$title = str_replace("{id}",$c['code'],post("title"));
$title = str_replace("{mail}",$u['email'],$title);
*/
$variables = [
'{id}',
'{prefix}',
'{title}',
'{file}',
'{name}',
'{surname}',
'{email}',
'{institution}',
'{country}',
'{abstract}',
];
?>
<div class="result-ajax"></div>
<form action="?ajax=mail-template&id={{get("id")}}&mid={{get("mid")}}&send" class="serialize" method="post">
@csrf
<input type="checkbox" name="" value="{{$user->email}}" onclick="if($(this).is(':checked'))
{
$('#to').val('{{$user->email}}');
} else {
$('#to').val('');
}" class="" id="coa">
To ({{$user->email}}):
<input type="text" name="to" id="to" class="form-control" required>
<script>
$(".mails").on("click",function(){
var output = $.map($('.mails:checked'), function(n, i){
return n.value;
}).join(',');
$("#cc").val(output);
});
$(".allmails").on("click",function(){
if($(this).is(":checked")) {
$("#cc").val($(this).val());
} else {
$("#cc").val("");
}
});
</script> <br>
<?php
$ccmails= array();
foreach($authors AS $ccm) {
if($user->email!=$ccm['email']) {
array_push($ccmails,$ccm['email']);
}
}
?>
<label><input type="checkbox" name="" value="<?php echo(implode(",",$ccmails)) ?>" class="allmails" id=""> All Corresponding Mails </label>
<br>
Bilgi (CC) (Separate with commas for multiple submissions):
<input class="form-control" type="text" name="cc" value="<?php // e(implode(",",$j['mails'])) ?>" id="cc" />
Subject:
<input type="text" name="title" value="{{$template->title2}}" id="" class="form-control">
<div class="row mt-10">
<?php foreach($variables AS $variable) {
?>
<div class="col">
<input type="text" editable="true" class="form-control" readonly value="{{$variable}}" >
</div>
<?php
} ?>
</div>
<br>
Body:
<textarea name="html" id="editor{{$template->id}}" cols="30" rows="10" class="">{{$template->html}}</textarea>
<button type="submit" class="btn btn-primary mt-5">Send</button>
</form>
<script>
CKEDITOR.replace( 'editor{{$template->id}}', {
language: '{{App::getLocale()}}',
removePlugins: 'image',
extraPlugins: 'base64image'
});
</script>
@include("scripts.serialize")
@@ -0,0 +1,74 @@
<?php
$query = apply_welded_filter(db("weld_logs"))->select(
"id",
'line_number',
'iso_number',
'spool_number',
'test_package_no',
'no_of_the_joint_as_per_as_built_survey AS joint_no',
'type_of_joint',
'type_of_welds',
'welding_date',
'welder_1',
'welder_2',
'member_no_1',
'material_no_1',
'outside_diameter_1',
'wall_thickness_1',
'member_no_2',
'material_no_2',
'outside_diameter_2',
'wall_thickness_2',
'date_of_vt',
'vt_result',
'rt_scope',
'rt_test_date',
'rt_result',
'ut_scope',
'ut_test_date',
'ut_result',
'mt_scope',
'mt_test_date',
'mt_result',
'pt_scope',
'pt_test_date',
'pt_result',
'pmi_scope',
'pmi_test_date',
'pwht',
'pwht_date',
'ferrite_scope',
'ferrite_result',
'date_of_ferrite_check',
);
if(!getesit("iso_number","")) {
$query->where("iso_number", "like", "%" . get("iso_number") . "%");
}
if(!getesit("d1","")) {
$query = $query->whereDate("welding_date", ">=", get("d1"));
$query = $query->whereDate("welding_date", "<=", get("d2"));
}
if(!getesit("spool_no","")) {
//$query->where("spool_number", get("spool_no"));
}
$query = $query->get();
foreach($query AS $data) {
if($data->welder_1 != "") $data->welder_1 = get_welder_id($data->welder_1);
if($data->welder_2 != "") $data->welder_2 = get_welder_id($data->welder_2);
}
echo json_encode_tr($query);
?>
@@ -0,0 +1,76 @@
<?php
$query = apply_welded_filter(db("weld_logs"))->select(
"id",
'line_number',
'iso_number',
'no_of_the_joint_as_per_as_built_survey AS joint_no',
'type_of_joint',
'type_of_welds',
'welding_date',
'spool_number',
'welder_1',
'welder_2',
'outside_diameter_1',
'wall_thickness_1',
'outside_diameter_2',
'wall_thickness_2',
'spool_status',
'spool_zone',
'vt_result',
'vt_request_date',
'test_laboratory_vt',
'pwht_request_date',
'test_laboratory_pwht',
'ht_request_date',
'test_laboratory_ht',
'rt_request_date',
'rt_result',
'pwht_result',
'ht_result',
'no_of_ferrite_check',
'test_laboratory_rt',
'ut_result',
'ut_request_date',
'test_laboratory_ut',
'ut_type',
'pt_result',
'pt_request_date',
'pt_result',
'test_laboratory_pt',
'mt_result',
'mt_request_date',
'test_laboratory_mt',
'pmi_result',
'pmi_request_date',
'test_laboratory_pmi',
'spool_release_date',
'ferrite_result',
'ferrite_request_date',
'ferrite_request_no',
'test_laboratory_ferrite',
);
if(!getesit("iso_number","")) {
$query->where("iso_number", "like", "%" . get("iso_number") . "%");
}
if(!getesit("spool_no","")) {
// $query->where("spool_number", get("spool_no"));
}
if(!getesit("d1","")) {
$query = $query->whereDate("welding_date", ">=", get("d1"));
$query = $query->whereDate("welding_date", "<=", get("d2"));
}
$query = $query->get();
foreach($query AS $data) {
if($data->welder_1 != "") $data->welder_1 = get_welder_id($data->welder_1);
if($data->welder_2 != "") $data->welder_2 = get_welder_id($data->welder_2);
}
echo json_encode_tr($query);
?>
@@ -0,0 +1,61 @@
<?php
$query = db("weld_logs")->select(
'id',
'ru_material_group_1',
'ru_material_group_2',
'iso_number',
'spool_number',
'no_of_the_joint_as_per_as_built_survey AS joint_no',
'type_of_joint',
'type_of_welds',
'welding_date',
'welder_1',
'welder_2',
'fit_up_date',
'mechanic_supervisor',
'mechanic_supervisor_control_date',
'welding_supervisor',
'welding_supervisor_control_date',
'element_code_1',
'pose_no_1',
'member_no_1',
'material_no_1',
'nps_1',
'thickness_by_asme_1',
'outside_diameter_1',
'wall_thickness_1',
'certificate_number_of_1',
'heat_number_1',
'element_code_2',
'member_no_2',
'material_no_2',
'nps_2',
'outside_diameter_2',
'wall_thickness_2',
'certificate_number_of_2',
'heat_number_2',
);
if(!getesit("iso_number","")) {
$query->where("iso_number", "like", "%" . get("iso_number") . "%");
}
if(!getesit("d1","")) {
$query = $query->whereDate("welding_date", ">=", get("d1"));
$query = $query->whereDate("welding_date", "<=", get("d2"));
}
if(!getesit("spool_no","")) {
//$query->where("spool_number", get("spool_no"));
}
$query = $query->get();
foreach($query AS $data) {
if($data->welder_1 != "") $data->welder_1 = get_welder_id($data->welder_1);
if($data->welder_2 != "") $data->welder_2 = get_welder_id($data->welder_2);
}
echo json_encode_tr($query);
?>
@@ -0,0 +1,40 @@
<?php
$query = db("weld_logs")->select(
'id',
'spool_number',
'no_of_the_joint_as_per_as_built_survey AS joint_no',
'wps_no',
'welding_materials_1',
'welding_materials_1_lot_no',
'welding_materials_1_certificate_no',
'welding_materials_2',
'welding_materials_2_lot_no',
'welding_materials_2_certificate_no',
'welding_materials_3',
'welding_materials_3_lot_no',
'welding_materials_3_certificate_no',
'test_package_no',
'remarks',
'ndt_release_date',
'spool_status',
'spool_zone',
);
if(!getesit("iso_number","")) {
$query->where("iso_number", "like", "%" . get("iso_number") . "%");
}
if(!getesit("spool_no","")) {
// $query->where("spool_number", get("spool_no"));
}
if(!getesit("d1","")) {
$query = $query->whereDate("welding_date", ">=", get("d1"));
$query = $query->whereDate("welding_date", "<=", get("d2"));
}
$query = $query->get();
echo json_encode_tr($query);
?>
@@ -0,0 +1,163 @@
<?php
// Tablo 1: Spool Bazlı Takip (SHOP) - Optimize: only get necessary fields
$shopQuery = db("paint_follow_ups")
->select(
"cycle",
"brend_name_1",
"brend_name_2",
"brend_name_3",
"akt_date_1",
"akt_date_2",
"akt_date_3",
"spool_no_joint_no"
)
->where("location", "SHOP")
->whereNotNull("cycle")
->orderBy("cycle");
$shopPaintFollowUps = method_exists($shopQuery, 'cursor') ? $shopQuery->cursor() : $shopQuery->get();
$spoolResults = [];
$spoolProcessed = []; // Track unique cycle+proses combinations
foreach ($shopPaintFollowUps as $row) {
$row = (array) $row;
$cycle = $row['cycle'] ?? '';
$spoolNo = $row['spool_no_joint_no'] ?? '';
if (empty($spoolNo)) {
continue;
}
// Check if painted (any akt_date is not null and not rejected)
$isPainted = false;
for ($dateIdx = 1; $dateIdx <= 3; $dateIdx++) {
$aktDate = $row['akt_date_' . $dateIdx] ?? null;
if (!rejected_date($aktDate)) {
$isPainted = true;
break;
}
}
// Process each brand for this spool
for ($k = 1; $k <= 3; $k++) {
$brand = $row['brend_name_' . $k] ?? null;
if (empty($brand)) {
continue;
}
$key = $cycle . '|' . $brand;
if (!isset($spoolProcessed[$key])) {
$spoolProcessed[$key] = [
'spools' => [], // Track unique spools
'painted_spools' => [] // Track unique painted spools
];
}
// Add spool to set (unique)
if (!in_array($spoolNo, $spoolProcessed[$key]['spools'])) {
$spoolProcessed[$key]['spools'][] = $spoolNo;
}
// Add to painted if painted
if ($isPainted && !in_array($spoolNo, $spoolProcessed[$key]['painted_spools'])) {
$spoolProcessed[$key]['painted_spools'][] = $spoolNo;
}
}
}
// Convert to results array for Tablo 1
foreach ($spoolProcessed as $key => $data) {
list($cycle, $brand) = explode('|', $key);
$spoolResults[] = [
"Paint System" => $cycle,
"Proses" => $brand,
"Spool Quantity" => count($data['spools']),
"Painted Spool Quantity" => count($data['painted_spools'])
];
}
// Tablo 2: Joint Bazlı Takip (Touch-up) - FIELD - Optimize: only get necessary fields
$fieldQuery = db("paint_follow_ups")
->select(
"cycle",
"brend_name_1",
"brend_name_2",
"brend_name_3",
"akt_date_1",
"akt_date_2",
"akt_date_3",
"spool_no_joint_no"
)
->where("location", "FIELD")
->whereNotNull("cycle")
->orderBy("cycle");
$fieldPaintFollowUps = method_exists($fieldQuery, 'cursor') ? $fieldQuery->cursor() : $fieldQuery->get();
$jointResults = [];
$jointProcessed = []; // Track unique cycle+proses combinations
foreach ($fieldPaintFollowUps as $row) {
$row = (array) $row;
$cycle = $row['cycle'] ?? '';
$jointNo = $row['spool_no_joint_no'] ?? '';
if (empty($jointNo)) {
continue;
}
// Process each brand for this joint
for ($k = 1; $k <= 3; $k++) {
$brand = $row['brend_name_' . $k] ?? null;
if (empty($brand)) {
continue;
}
$key = $cycle . '|' . $brand;
if (!isset($jointProcessed[$key])) {
$jointProcessed[$key] = [
'joints' => [], // Track unique joints
'total_joints_set' => [] // Track all joints for total count
];
}
// Add joint to set (unique) for touch-up count
if (!in_array($jointNo, $jointProcessed[$key]['joints'])) {
$jointProcessed[$key]['joints'][] = $jointNo;
}
// Add to total joints set
if (!in_array($jointNo, $jointProcessed[$key]['total_joints_set'])) {
$jointProcessed[$key]['total_joints_set'][] = $jointNo;
}
}
}
// Convert to results array for Tablo 2
foreach ($jointProcessed as $key => $data) {
list($cycle, $brand) = explode('|', $key);
// Total joints for this cycle (all joints in FIELD location for this cycle)
$totalJoints = db("paint_follow_ups")
->where("location", "FIELD")
->where("cycle", $cycle)
->distinct()
->count("spool_no_joint_no");
$jointResults[] = [
"Paint System" => $cycle,
"Proses" => $brand,
"Touch-up Joints Quantity" => count($data['joints']),
"Joints Quantity" => $totalJoints
];
}
// Return both tables
$response = [
'spool_data' => $spoolResults,
'joint_data' => $jointResults
];
echo json_encode_tr($response);
?>
@@ -0,0 +1,146 @@
<?php
// Supports tablosunu çek
$supportsQuery = db("supports")
->select("status", "total_weight", "quantity", "zone", "drawing_no", "line_number")
->whereNotNull('status')
->orderBy("zone");
$supports = method_exists($supportsQuery, 'cursor') ? $supportsQuery->cursor() : $supportsQuery->get();
// Weld_logs'tan project ve design_area mapping'i oluştur (performans için)
$weldLogsMap = [];
if (count($supports) > 0) {
$drawingNos = [];
$lineNumbers = [];
foreach ($supports as $sup) {
if (!empty($sup->drawing_no)) {
$drawingNos[] = $sup->drawing_no;
}
if (!empty($sup->line_number)) {
$lineNumbers[] = $sup->line_number;
}
}
if (!empty($drawingNos) || !empty($lineNumbers)) {
$weldLogsQuery = db("weld_logs")
->select("iso_number", "line_number", "project", "design_area");
if (!empty($drawingNos)) {
$weldLogsQuery->whereIn("iso_number", array_unique($drawingNos));
}
if (!empty($lineNumbers)) {
$weldLogsQuery->whereIn("line_number", array_unique($lineNumbers));
}
$weldLogs = $weldLogsQuery->get();
foreach ($weldLogs as $wl) {
$key = ($wl->iso_number ?? '') . '|' . ($wl->line_number ?? '');
if (!empty($key) && $key !== '|') {
$weldLogsMap[$key] = [
'project' => $wl->project ?? null,
'design_area' => $wl->design_area ?? null
];
}
}
}
}
$results = [];
$projectAreaStats = []; // Project+Area bazında istatistikler için
foreach ($supports as $row) {
$row = (array) $row;
$status = $row['status'] ?? '';
$zone = $row['zone'] ?? '';
$drawingNo = $row['drawing_no'] ?? '';
$lineNumber = $row['line_number'] ?? '';
// Weld_logs mapping'den project ve design_area'yı al
$key = $drawingNo . '|' . $lineNumber;
$weldLogData = $weldLogsMap[$key] ?? null;
// Project: weld_logs.project varsa onu kullan, yoksa zone'u kullan
$project = !empty($weldLogData['project']) ? strtoupper($weldLogData['project']) : strtoupper($zone);
// Area: weld_logs.design_area varsa onu kullan, yoksa zone'u kullan
$area = !empty($weldLogData['design_area']) ? strtoupper($weldLogData['design_area']) : strtoupper($zone);
// Determine status category
// Gerçek status değerleri: "", "0K", "OK"
$statusCategory = 'Other';
$statusTrimmed = trim($status);
// OK = Installed/Complete Support
if (strtoupper($statusTrimmed) === 'OK') {
$statusCategory = 'Installed Support';
}
// 0K veya boş = Incomplete (henüz tamamlanmamış)
elseif (strtoupper($statusTrimmed) === '0K' || empty($statusTrimmed)) {
$statusCategory = 'Incomplete Support Installation';
}
// Eski mantık (eğer gelecekte farklı status değerleri eklenirse)
else {
$statusLower = strtolower($statusTrimmed);
// Önce incomplete kontrolü (daha spesifik)
if (stripos($statusLower, 'incomplete') !== false) {
if (stripos($statusLower, 'weld') !== false) {
$statusCategory = 'Weld-Incomplete Support';
} else {
$statusCategory = 'Incomplete Support Installation';
}
}
// Sonra complete kontrolü (weld ile birlikte)
elseif (stripos($statusLower, 'weld') !== false && stripos($statusLower, 'complete') !== false) {
$statusCategory = 'Weld-Complete Support';
}
// Son olarak installed veya complete (genel)
elseif (stripos($statusLower, 'installed') !== false || stripos($statusLower, 'complete') !== false) {
$statusCategory = 'Installed Support';
}
}
$key = $project . '|' . $area;
if (!isset($projectAreaStats[$key])) {
$projectAreaStats[$key] = [
'total' => 0,
'installed' => 0
];
}
$quantity = (int) ($row['quantity'] ?? 0);
$projectAreaStats[$key]['total'] += $quantity;
// Installed sayısını hesapla - Installed Support veya Weld-Complete Support
if ($statusCategory === 'Installed Support' || $statusCategory === 'Weld-Complete Support') {
$projectAreaStats[$key]['installed'] += $quantity;
}
$results[] = [
'Project' => $project,
'Area' => $area,
'Status' => $statusCategory,
'Weight' => (double) ($row['total_weight'] ?? 0), // kg bazında
'Quantity' => (int) $quantity, // adet bazında
'Original Status' => $status
];
}
// Progress hesapla ve ekle
foreach ($results as &$result) {
$key = $result['Project'] . '|' . $result['Area'];
$total = $projectAreaStats[$key]['total'] ?? 0;
$installed = $projectAreaStats[$key]['installed'] ?? 0;
$progress = 0;
if ($total > 0) {
$progress = round(($installed / $total) * 100, 2);
}
$result['Progress'] = $progress;
}
echo json_encode_tr($results);
?>
@@ -0,0 +1,96 @@
<?php
// Filtered for Supports
$materials = db("materials")
->select("ru_group", "short_name")
->get()
->pluck("short_name", "ru_group")
->toArray();
// İzin verilen material grupları: CS, SS, NI (task gereksinimi)
$allowedMaterials = ['CS', 'SS', 'NI'];
$query = apply_welded_filter(
db("weld_logs")
->select(
"ru_material_group_1",
"project",
"welding_date",
"fit_up_date",
"nps_1"
)
->where('piping_type', 'like', '%Support%') // Filter for Supports
->orWhere('piping_type', 'like', '%Опора%') // Russian for Support
->orderBy("id")
);
$iterator = method_exists($query, 'cursor') ? $query->cursor() : $query->get();
$processedData = [];
foreach ($iterator as $row) {
$row = (array) $row;
try {
$ru_material_group_1 = $materials[$row['ru_material_group_1']] ?? $row['ru_material_group_1'];
} catch (\Throwable $th) {
$ru_material_group_1 = $row['ru_material_group_1'];
}
if (empty($ru_material_group_1)) {
$ru_material_group_1 = 'Unknown';
}
$ru_material_group_1_upper = strtoupper(trim($ru_material_group_1));
if (stripos($ru_material_group_1_upper, 'POLIMER') !== false ||
stripos($ru_material_group_1_upper, 'POLYMER') !== false ||
!in_array($ru_material_group_1_upper, $allowedMaterials)) {
continue;
}
if (!isset($processedData[$ru_material_group_1])) {
$processedData[$ru_material_group_1] = [
'Welded Joints Quantity' => 0,
'Welded Joints WDI' => 0,
'Fit-Up Quantity (Not welded)' => 0,
'Fit-Up WDI (Not welded)' => 0,
'Weld Backlog' => 0,
];
}
$nps_1 = (double) ($row['nps_1'] ?? 0);
if ($row['welding_date']) {
// Welded
$processedData[$ru_material_group_1]['Welded Joints Quantity']++;
$processedData[$ru_material_group_1]['Welded Joints WDI'] += $nps_1;
} elseif ($row['fit_up_date']) {
// Fit-Up but not welded
$processedData[$ru_material_group_1]['Fit-Up Quantity (Not welded)']++;
$processedData[$ru_material_group_1]['Fit-Up WDI (Not welded)'] += $nps_1;
} else {
// Backlog
$processedData[$ru_material_group_1]['Weld Backlog']++;
}
}
// Convert to results array for pivot grid
$results = [];
foreach ($processedData as $material => $data) {
$total = $data['Welded Joints Quantity'] + $data['Fit-Up Quantity (Not welded)'] + $data['Weld Backlog'];
$progress = $total > 0 ? round(($data['Welded Joints Quantity'] / $total) * 100, 2) : 0;
$results[] = [
'Material' => $material,
'Welded Joints Quantity' => $data['Welded Joints Quantity'],
'Welded Joints WDI' => round($data['Welded Joints WDI'], 2),
'Fit-Up Quantity (Not welded)' => $data['Fit-Up Quantity (Not welded)'],
'Fit-Up WDI (Not welded)' => round($data['Fit-Up WDI (Not welded)'], 2),
'Weld Backlog' => $data['Weld Backlog'],
'Progress' => $progress,
'WDI' => round($data['Welded Joints WDI'], 2),
'Count' => $data['Welded Joints Quantity']
];
}
echo json_encode_tr($results);
?>
@@ -0,0 +1,100 @@
<?php
/**
* @api-readonly
* Returns material performance statistics
*/
$materials = db("materials")
->select("ru_group", "short_name")
->get()
->pluck("short_name", "ru_group")
->toArray();
// İzin verilen material grupları: CS, SS, NI (task gereksinimi)
$allowedMaterials = ['CS', 'SS', 'NI'];
$query = apply_welded_filter(
db("weld_logs")
->select(
"ru_material_group_1",
"project",
"welding_date",
"fit_up_date",
"nps_1"
)
->orderBy("id")
);
$iterator = method_exists($query, 'cursor') ? $query->cursor() : $query->get();
$processedData = [];
foreach ($iterator as $row) {
$row = (array) $row;
try {
$ru_material_group_1 = $materials[$row['ru_material_group_1']] ?? $row['ru_material_group_1'];
} catch (\Throwable $th) {
$ru_material_group_1 = $row['ru_material_group_1'];
}
if (empty($ru_material_group_1)) {
$ru_material_group_1 = 'Unknown';
}
$ru_material_group_1_upper = strtoupper(trim($ru_material_group_1));
if (stripos($ru_material_group_1_upper, 'POLIMER') !== false ||
stripos($ru_material_group_1_upper, 'POLYMER') !== false ||
!in_array($ru_material_group_1_upper, $allowedMaterials)) {
continue;
}
if (!isset($processedData[$ru_material_group_1])) {
$processedData[$ru_material_group_1] = [
'Welded Joints Quantity' => 0,
'Welded Joints WDI' => 0,
'Fit-Up Quantity (Not welded)' => 0,
'Fit-Up WDI (Not welded)' => 0,
'Weld Backlog' => 0,
];
}
$nps_1 = (double) ($row['nps_1'] ?? 0);
if ($row['welding_date']) {
// Welded
$processedData[$ru_material_group_1]['Welded Joints Quantity']++;
$processedData[$ru_material_group_1]['Welded Joints WDI'] += $nps_1;
} elseif ($row['fit_up_date']) {
// Fit-Up but not welded
$processedData[$ru_material_group_1]['Fit-Up Quantity (Not welded)']++;
$processedData[$ru_material_group_1]['Fit-Up WDI (Not welded)'] += $nps_1;
} else {
// Backlog
$processedData[$ru_material_group_1]['Weld Backlog']++;
}
}
// Convert to results array for pivot grid
// Each row represents one material with all columns
$results = [];
foreach ($processedData as $material => $data) {
$total = $data['Welded Joints Quantity'] + $data['Fit-Up Quantity (Not welded)'] + $data['Weld Backlog'];
$progress = $total > 0 ? round(($data['Welded Joints Quantity'] / $total) * 100, 2) : 0;
$results[] = [
'Material' => $material,
'Welded Joints Quantity' => $data['Welded Joints Quantity'],
'Welded Joints WDI' => round($data['Welded Joints WDI'], 2),
'Fit-Up Quantity (Not welded)' => $data['Fit-Up Quantity (Not welded)'],
'Fit-Up WDI (Not welded)' => round($data['Fit-Up WDI (Not welded)'], 2),
'Weld Backlog' => $data['Weld Backlog'],
'Progress' => $progress,
// For Welded Supports Sum (WDI sum)
'WDI' => round($data['Welded Joints WDI'], 2),
// For Welded Count Sum (count)
'Count' => $data['Welded Joints Quantity']
];
}
echo json_encode_tr($results);
?>
@@ -0,0 +1,120 @@
<?php
set_time_limit(0);
ini_set('max_execution_time', '0');
$other = db("other")->get();
$oth = [];
foreach($other AS $o) {
$oth[$o->cid][str_slug($o->alan)] = $o->deger;
}
$content = db('content')->where('type','Articles')->get();
/*
foreach($content AS $c) {
$volume = db("content")->where("slug",$c->kid)->pluck("kid")->first();
$insert = [
'title' => $c->title,
'slug' => $c->slug,
'kid' => $c->kid,
'files' => @$oth[$c->slug]['link'],
'html' => $c->html,
'view' => $c->view,
'comment' => $c->comment,
'eye' => $c->eye,
'cited' => $c->cited,
'scopus_id' => $c->scopus_id,
'cited_scopus' => $c->cited_scopus,
'volume' => $volume,
'issue' => $c->kid,
'json' => json_encode_tr(@$oth[$c->slug])
];
try {
ekle2($insert,'articles');
print2("INSERT {$c->slug}");
} catch (\Throwable $th) {
db('articles')
->where('slug',$c->slug)
->update($insert);
// echo($th);
print2("UPDATE {$c->slug}");
}
}
$content = db('content')->where('type','Volume')->get();
foreach($content AS $c) {
$insert = [
'title' => $c->title,
'slug' => $c->slug,
'kid' => $c->kid,
'y' => 1,
'html' => $c->html,
'json' => json_encode_tr(@$oth[$c->slug])
];
try {
ekle2($insert,'volumes');
print2("VOLUME INSERT {$c->slug}");
} catch (\Throwable $th) {
db('volumes')
->where('slug',$c->slug)
->update($insert);
// echo($th);
print2("VOLUME UPDATE {$c->slug}");
}
}
*/
/*
$content = db('content')->where('type','Issue')->get();
foreach($content AS $c) {
$insert = [
'title' => $c->title,
'slug' => $c->slug,
'kid' => $c->kid,
'y' => 1,
'html' => $c->html,
'json' => json_encode_tr(@$oth[$c->slug])
];
try {
ekle2($insert,'issues');
print2("ISSUE INSERT {$c->slug}");
} catch (\Throwable $th) {
db('issues')
->where('slug',$c->slug)
->update($insert);
// echo($th);
print2("ISSUE UPDATE {$c->slug}");
}
}
*/
$users = db("uyeler")->simplePaginate(5000);
foreach($users AS $u) {
if($u->ilk_sifre=="") $u->ilk_sifre = rand(111111,999999);
$password = Hash::make($u->ilk_sifre);
$data = [
'name' => $u->adi,
'surname' => $u->soyadi,
'level' => "Client",
'email' => $u->mail,
'country' => $u->country,
'institution' => $u->institution,
'prefix' => $u->prefix,
'blacklist' => $u->blacklist,
'recover' => $u->ilk_sifre,
'phone' => $u->phone,
'note' => $u->note,
'password' => $password,
];
firstOrUpdate($data,"users",[
'email'=>$u->mail,
'phone'=>$u->phone,
]);
}
?>
@@ -0,0 +1,11 @@
<?php
$mto = db("m_t_o_s")
->where("component_code_id", trim(get("component_code_id")))
->where(function($query) {
$query->orWhere("odmm_1", get("odmm"));
$query->orWhere("odmm_2", get("odmm"));
})
->first();
echo json_encode_tr($mto);
?>

Some files were not shown because too many files have changed in this diff Show More