ikinci temizlik tamamlandı
This commit is contained in:
@@ -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',
|
||||
});
|
||||
Vendored
+32
@@ -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>
|
||||
@@ -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;
|
||||
@@ -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()
|
||||
]);
|
||||
}
|
||||
?>
|
||||
@@ -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 + ' <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">×</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
Reference in New Issue
Block a user