Logic fixed
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Yakıt Takip Modülü
|
||||
# Yakıt Takip Uygulaması
|
||||
|
||||
Akaryakıt istasyonu için geliştirilmiş modern ve kullanıcı dostu yönetim sistemi.
|
||||
|
||||
@@ -206,4 +206,4 @@ Proje hakkında sorularınız için lütfen iletişime geçin.
|
||||
|
||||
---
|
||||
|
||||
**Yakıt Takip Modülü** - Modern Akaryakıt İstasyonu Yönetim Sistemi
|
||||
**Yakıt Takip Uygulaması** - Modern Akaryakıt İstasyonu Yönetim Sistemi
|
||||
@@ -1,4 +1,4 @@
|
||||
# Yakıt Takip Modülü - Kapsamlı Proje Dokümantasyonu
|
||||
# Yakıt Takip Uygulaması - Kapsamlı Proje Dokümantasyonu
|
||||
|
||||
## 📋 İçerik Tablosu
|
||||
1. [Proje Genel Bakış](#proje-genel-bakış)
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
## 🎯 Proje Genel Bakış
|
||||
|
||||
Yakıt Takip Modülü, akaryakıt istasyonları için geliştirilmiş, modern ve kullanıcı dostu bir yönetim sistemidir. Sistem, yakıt ikmal süreçlerini dijitalleştirerek verimliliği artırmayı ve süreç takibini kolaylaştırmayı hedefler.
|
||||
Yakıt Takip Uygulaması, akaryakıt istasyonları için geliştirilmiş, modern ve kullanıcı dostu bir yönetim sistemidir. Sistem, yakıt ikmal süreçlerini dijitalleştirerek verimliliği artırmayı ve süreç takibini kolaylaştırmayı hedefler.
|
||||
|
||||
### Ana Hedefler
|
||||
- **Dijital Dönüşüm**: Kağıt bazlı süreçlerin dijitalleştirilmesi
|
||||
@@ -1732,6 +1732,6 @@ echo "Recovery completed. Services restarting..."
|
||||
|
||||
---
|
||||
|
||||
**Bu dokümantasyon Yakıt Takip Modülü projesinin kapsamlı süreçlerini ve teknik detaylarını içermektedir. Güncel kalmak için düzenli olarak gözden geçirilmeli ve güncellenmelidir.**
|
||||
**Bu dokümantasyon Yakıt Takip Uygulaması projesinin kapsamlı süreçlerini ve teknik detaylarını içermektedir. Güncel kalmak için düzenli olarak gözden geçirilmeli ve güncellenmelidir.**
|
||||
|
||||
*Son güncelleme: 2024-11-05*
|
||||
@@ -1,6 +1,6 @@
|
||||
# Yakıt Takip Modülü - Dokümantasyon
|
||||
# Yakıt Takip Uygulaması - Dokümantasyon
|
||||
|
||||
Bu klasörde Yakıt Takip Modülü'nün tüm dokümantasyon dosyaları bulunmaktadır.
|
||||
Bu klasörde Yakıt Takip Uygulaması'nın tüm dokümantasyon dosyaları bulunmaktadır.
|
||||
|
||||
## 📚 Dokümantasyon Dosyaları
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>⛽</text></svg>" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Yakıt Takip Modülü</title>
|
||||
<title>Yakıt Takip Uygulaması</title>
|
||||
<!-- Font Awesome CDN -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
%sveltekit.head%
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let user = null;
|
||||
let personnel = [];
|
||||
let units = [];
|
||||
let personnel = [];
|
||||
let units = [];
|
||||
let loading = true;
|
||||
let error = '';
|
||||
let showAddModal = false;
|
||||
@@ -11,15 +11,15 @@
|
||||
let selectedPersonnel = null;
|
||||
|
||||
// Form değişkenleri
|
||||
let formData = {
|
||||
full_name: '',
|
||||
rank: '',
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
let formData = {
|
||||
full_name: '',
|
||||
rank: '',
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
const userData = localStorage.getItem('user');
|
||||
@@ -36,10 +36,10 @@
|
||||
|
||||
async function loadPersonnel() {
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel');
|
||||
const response = await fetch('/api/unit-personnel');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
personnel = data.fuelPersonnel || [];
|
||||
personnel = data.goodsManagers || [];
|
||||
} else {
|
||||
error = 'Personel bilgileri yüklenemedi.';
|
||||
}
|
||||
@@ -68,18 +68,18 @@
|
||||
return units.find((unit) => unit.id === id)?.name || 'Belirtilmemiş';
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formData = {
|
||||
full_name: '',
|
||||
rank: '',
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
selectedPersonnel = null;
|
||||
}
|
||||
function resetForm() {
|
||||
formData = {
|
||||
full_name: '',
|
||||
rank: '',
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
selectedPersonnel = null;
|
||||
}
|
||||
|
||||
function openAddModal() {
|
||||
resetForm();
|
||||
@@ -88,15 +88,15 @@
|
||||
|
||||
function openEditModal(person) {
|
||||
selectedPersonnel = person;
|
||||
formData = {
|
||||
full_name: person.full_name,
|
||||
rank: person.rank,
|
||||
registration_number: person.registration_number,
|
||||
tc_kimlik: person.tc_kimlik,
|
||||
phone: person.phone,
|
||||
unit_id: person.unit_id || '',
|
||||
is_active: person.is_active
|
||||
};
|
||||
formData = {
|
||||
full_name: person.full_name,
|
||||
rank: person.rank,
|
||||
registration_number: person.registration_number,
|
||||
tc_kimlik: person.tc_kimlik,
|
||||
phone: person.phone,
|
||||
unit_id: person.unit_id || '',
|
||||
is_active: person.is_active
|
||||
};
|
||||
showEditModal = true;
|
||||
}
|
||||
|
||||
@@ -107,10 +107,10 @@
|
||||
}
|
||||
|
||||
async function handleAddPersonnel() {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/^[0-9]{11}$/.test(formData.tc_kimlik)) {
|
||||
error = 'TC Kimlik numarası 11 haneli olmalıdır.';
|
||||
@@ -118,7 +118,7 @@
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel', {
|
||||
const response = await fetch('/api/unit-personnel', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -142,10 +142,10 @@
|
||||
}
|
||||
|
||||
async function handleUpdatePersonnel() {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/^[0-9]{11}$/.test(formData.tc_kimlik)) {
|
||||
error = 'TC Kimlik numarası 11 haneli olmalıdır.';
|
||||
@@ -153,7 +153,7 @@
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel', {
|
||||
const response = await fetch('/api/unit-personnel', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -185,7 +185,7 @@
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel', {
|
||||
const response = await fetch('/api/unit-personnel', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -209,7 +209,7 @@
|
||||
|
||||
async function togglePersonnelStatus(person) {
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel', {
|
||||
const response = await fetch('/api/unit-personnel', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
export let user = null;
|
||||
|
||||
let personnel = [];
|
||||
let units = [];
|
||||
let loading = true;
|
||||
let error = '';
|
||||
let showAddModal = false;
|
||||
@@ -19,27 +18,13 @@ let formData = {
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
await loadUnits();
|
||||
await loadPersonnel();
|
||||
});
|
||||
|
||||
async function loadUnits() {
|
||||
try {
|
||||
const response = await fetch('/api/units');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
units = data.units || [];
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Load units error:', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPersonnel() {
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel');
|
||||
@@ -64,7 +49,6 @@ function resetForm() {
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
selectedPersonnel = null;
|
||||
@@ -83,7 +67,6 @@ function openEditModal(person) {
|
||||
registration_number: person.registration_number,
|
||||
tc_kimlik: person.tc_kimlik,
|
||||
phone: person.phone,
|
||||
unit_id: person.unit_id || '',
|
||||
is_active: person.is_active
|
||||
};
|
||||
showEditModal = true;
|
||||
@@ -96,7 +79,7 @@ function openEditModal(person) {
|
||||
}
|
||||
|
||||
async function handleAddPersonnel() {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id) {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
@@ -131,7 +114,7 @@ function openEditModal(person) {
|
||||
}
|
||||
|
||||
async function handleUpdatePersonnel() {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id) {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
@@ -295,16 +278,25 @@ function openEditModal(person) {
|
||||
<span class="detail-value">{person.tc_kimlik}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon">
|
||||
<i class="fas fa-phone"></i>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<span class="detail-label">İrtibat:</span>
|
||||
<span class="detail-value">{person.phone}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon">
|
||||
<i class="fas fa-phone"></i>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<span class="detail-label">İrtibat:</span>
|
||||
<span class="detail-value">{person.phone}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon">
|
||||
<i class="fas fa-gas-pump"></i>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<span class="detail-label">Görev Yeri:</span>
|
||||
<span class="detail-value">Fuel Station</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="personnel-actions">
|
||||
<button class="btn btn-sm btn-secondary" on:click={() => openEditModal(person)}>
|
||||
@@ -399,20 +391,6 @@ function openEditModal(person) {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="unit_id">Birlik</label>
|
||||
<select
|
||||
id="unit_id"
|
||||
class="form-input"
|
||||
bind:value={formData.unit_id}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn btn-secondary" on:click={closeModal}>İptal</button>
|
||||
<button type="submit" class="btn btn-primary">Kaydet</button>
|
||||
@@ -487,20 +465,6 @@ function openEditModal(person) {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-unit_id">Birlik</label>
|
||||
<select
|
||||
id="edit-unit_id"
|
||||
class="form-input"
|
||||
bind:value={formData.unit_id}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="checkbox-label">
|
||||
<input
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
// Props
|
||||
export let user = null;
|
||||
|
||||
let vehicles = [];
|
||||
let vehicles = [];
|
||||
let units = [];
|
||||
let loading = true;
|
||||
let error = '';
|
||||
let showAddModal = false;
|
||||
@@ -12,21 +13,35 @@
|
||||
let selectedVehicle = null;
|
||||
|
||||
// Form değişkenleri
|
||||
let formData = {
|
||||
brand: '',
|
||||
model: '',
|
||||
year: new Date().getFullYear(),
|
||||
plate: '',
|
||||
fuel_type: 'Benzin',
|
||||
fuel_capacity: 50,
|
||||
current_fuel: 0,
|
||||
yazlik_mukannen: 0,
|
||||
kislik_mukannen: 0
|
||||
};
|
||||
let formData = {
|
||||
brand: '',
|
||||
model: '',
|
||||
year: new Date().getFullYear(),
|
||||
plate: '',
|
||||
unit_id: '',
|
||||
fuel_type: 'Benzin',
|
||||
fuel_capacity: 50,
|
||||
current_fuel: 0,
|
||||
yazlik_mukannen: 0,
|
||||
kislik_mukannen: 0
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
await loadVehicles();
|
||||
});
|
||||
onMount(async () => {
|
||||
await loadUnits();
|
||||
await loadVehicles();
|
||||
});
|
||||
|
||||
async function loadUnits() {
|
||||
try {
|
||||
const response = await fetch('/api/units');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
units = data.units || [];
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Load units error:', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadVehicles() {
|
||||
try {
|
||||
@@ -45,18 +60,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formData = {
|
||||
brand: '',
|
||||
model: '',
|
||||
year: new Date().getFullYear(),
|
||||
plate: '',
|
||||
fuel_type: 'Benzin',
|
||||
fuel_capacity: 50,
|
||||
current_fuel: 0,
|
||||
yazlik_mukannen: 0,
|
||||
kislik_mukannen: 0
|
||||
};
|
||||
function resetForm() {
|
||||
formData = {
|
||||
brand: '',
|
||||
model: '',
|
||||
year: new Date().getFullYear(),
|
||||
plate: '',
|
||||
unit_id: '',
|
||||
fuel_type: 'Benzin',
|
||||
fuel_capacity: 50,
|
||||
current_fuel: 0,
|
||||
yazlik_mukannen: 0,
|
||||
kislik_mukannen: 0
|
||||
};
|
||||
selectedVehicle = null;
|
||||
}
|
||||
|
||||
@@ -65,19 +81,20 @@
|
||||
showAddModal = true;
|
||||
}
|
||||
|
||||
function openEditModal(vehicle) {
|
||||
selectedVehicle = vehicle;
|
||||
formData = {
|
||||
brand: vehicle.brand,
|
||||
model: vehicle.model,
|
||||
year: vehicle.year,
|
||||
plate: vehicle.plate,
|
||||
fuel_type: vehicle.fuel_type || 'Benzin',
|
||||
fuel_capacity: vehicle.fuel_capacity || 50,
|
||||
current_fuel: vehicle.current_fuel || 0,
|
||||
yazlik_mukannen: vehicle.yazlik_mukannen || 0,
|
||||
kislik_mukannen: vehicle.kislik_mukannen || 0
|
||||
};
|
||||
function openEditModal(vehicle) {
|
||||
selectedVehicle = vehicle;
|
||||
formData = {
|
||||
brand: vehicle.brand,
|
||||
model: vehicle.model,
|
||||
year: vehicle.year,
|
||||
plate: vehicle.plate,
|
||||
unit_id: vehicle.unit_id ? vehicle.unit_id.toString() : '',
|
||||
fuel_type: vehicle.fuel_type || 'Benzin',
|
||||
fuel_capacity: vehicle.fuel_capacity || 50,
|
||||
current_fuel: vehicle.current_fuel || 0,
|
||||
yazlik_mukannen: vehicle.yazlik_mukannen || 0,
|
||||
kislik_mukannen: vehicle.kislik_mukannen || 0
|
||||
};
|
||||
showEditModal = true;
|
||||
}
|
||||
|
||||
@@ -87,30 +104,43 @@
|
||||
resetForm();
|
||||
}
|
||||
|
||||
function validateMukannen(value) {
|
||||
// Sadece pozitif tam sayı kabul et
|
||||
return /^[0-9]*$/.test(value) && value >= 0;
|
||||
function validateMukannen(value) {
|
||||
if (value === '' || value === null || value === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const normalizedValue = typeof value === 'number' ? value : parseFloat(value.toString().replace(',', '.'));
|
||||
return !isNaN(normalizedValue) && normalizedValue >= 0;
|
||||
}
|
||||
|
||||
function getUnitName(unitId, unitList = units) {
|
||||
const id = parseInt(unitId);
|
||||
return unitList.find((unit) => unit.id === id)?.name || 'Belirtilmemiş';
|
||||
}
|
||||
|
||||
async function handleAddVehicle() {
|
||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate || !formData.fuel_type || !formData.fuel_capacity) {
|
||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate || !formData.unit_id || !formData.fuel_type || !formData.fuel_capacity) {
|
||||
error = 'Tüm zorunlu alanları doldurun.';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!validateMukannen(formData.yazlik_mukannen) || !validateMukannen(formData.kislik_mukannen)) {
|
||||
error = 'Mukannen değerleri sadece rakam içermelidir.';
|
||||
error = 'Mukannen değerleri sayısal olmalı ve negatif olamaz.';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/vehicles', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
try {
|
||||
const payload = {
|
||||
...formData,
|
||||
unit_id: parseInt(formData.unit_id)
|
||||
};
|
||||
const response = await fetch('/api/vehicles', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
@@ -128,27 +158,29 @@
|
||||
}
|
||||
|
||||
async function handleUpdateVehicle() {
|
||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate || !formData.fuel_type || !formData.fuel_capacity) {
|
||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate || !formData.unit_id || !formData.fuel_type || !formData.fuel_capacity) {
|
||||
error = 'Tüm zorunlu alanları doldurun.';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!validateMukannen(formData.yazlik_mukannen) || !validateMukannen(formData.kislik_mukannen)) {
|
||||
error = 'Mukannen değerleri sadece rakam içermelidir.';
|
||||
error = 'Mukannen değerleri sayısal olmalı ve negatif olamaz.';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/vehicles', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: selectedVehicle.id,
|
||||
...formData
|
||||
}),
|
||||
});
|
||||
try {
|
||||
const payload = {
|
||||
id: selectedVehicle.id,
|
||||
...formData,
|
||||
unit_id: parseInt(formData.unit_id)
|
||||
};
|
||||
const response = await fetch('/api/vehicles', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
@@ -253,6 +285,9 @@
|
||||
<span class="plate-badge"><i class="fas fa-car"></i> {vehicle.plate}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="vehicle-unit">
|
||||
<i class="fas fa-building"></i> {vehicle.unit_name || getUnitName(vehicle.unit_id, units)}
|
||||
</p>
|
||||
<div class="vehicle-actions">
|
||||
<button class="btn btn-sm btn-secondary" on:click={() => openEditModal(vehicle)}>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
@@ -318,17 +353,31 @@
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="plate">Plaka</label>
|
||||
<input
|
||||
id="plate"
|
||||
type="text"
|
||||
class="form-input"
|
||||
bind:value={formData.plate}
|
||||
placeholder="34ABC123"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="plate">Plaka</label>
|
||||
<input
|
||||
id="plate"
|
||||
type="text"
|
||||
class="form-input"
|
||||
bind:value={formData.plate}
|
||||
placeholder="34ABC123"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="unit_id">Birlik</label>
|
||||
<select
|
||||
id="unit_id"
|
||||
class="form-input"
|
||||
bind:value={formData.unit_id}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="fuel_type">Yakıt Tipi</label>
|
||||
<select
|
||||
@@ -379,10 +428,9 @@
|
||||
class="form-input"
|
||||
bind:value={formData.yazlik_mukannen}
|
||||
min="0"
|
||||
step="1"
|
||||
step="0.01"
|
||||
placeholder="0"
|
||||
pattern="[0-9]*"
|
||||
inputmode="numeric"
|
||||
inputmode="decimal"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -393,10 +441,9 @@
|
||||
class="form-input"
|
||||
bind:value={formData.kislik_mukannen}
|
||||
min="0"
|
||||
step="1"
|
||||
step="0.01"
|
||||
placeholder="0"
|
||||
pattern="[0-9]*"
|
||||
inputmode="numeric"
|
||||
inputmode="decimal"
|
||||
/>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
@@ -451,17 +498,31 @@
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-plate">Plaka</label>
|
||||
<input
|
||||
id="edit-plate"
|
||||
type="text"
|
||||
class="form-input"
|
||||
bind:value={formData.plate}
|
||||
placeholder="34ABC123"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-plate">Plaka</label>
|
||||
<input
|
||||
id="edit-plate"
|
||||
type="text"
|
||||
class="form-input"
|
||||
bind:value={formData.plate}
|
||||
placeholder="34ABC123"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-unit_id">Birlik</label>
|
||||
<select
|
||||
id="edit-unit_id"
|
||||
class="form-input"
|
||||
bind:value={formData.unit_id}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-fuel_type">Yakıt Tipi</label>
|
||||
<select
|
||||
@@ -512,10 +573,9 @@
|
||||
class="form-input"
|
||||
bind:value={formData.yazlik_mukannen}
|
||||
min="0"
|
||||
step="1"
|
||||
step="0.01"
|
||||
placeholder="0"
|
||||
pattern="[0-9]*"
|
||||
inputmode="numeric"
|
||||
inputmode="decimal"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -526,10 +586,9 @@
|
||||
class="form-input"
|
||||
bind:value={formData.kislik_mukannen}
|
||||
min="0"
|
||||
step="1"
|
||||
step="0.01"
|
||||
placeholder="0"
|
||||
pattern="[0-9]*"
|
||||
inputmode="numeric"
|
||||
inputmode="decimal"
|
||||
/>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
@@ -664,6 +723,15 @@
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.vehicle-unit {
|
||||
margin: 0 0 1rem;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.vehicle-info h3 {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
@@ -826,4 +894,4 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Yakıt Takip Modülü</title>
|
||||
<title>Yakıt Takip Uygulaması</title>
|
||||
<meta name="description" content="Akaryakıt İstasyonu Yönetim Sistemi" />
|
||||
</svelte:head>
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<img src="/logo.png" alt="YTP Logo" class="app-logo" />
|
||||
</div>
|
||||
<h1 class="app-title">Giriş</h1>
|
||||
<p class="app-subtitle">Yakıt Takip Modülü</p>
|
||||
<p class="app-subtitle">Yakıt Takip Uygulaması</p>
|
||||
</div>
|
||||
|
||||
<form on:submit|preventDefault={handleLogin} class="space-y-6">
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
|
||||
export function GET() {
|
||||
return json({ status: 'ok' });
|
||||
}
|
||||
@@ -159,7 +159,7 @@
|
||||
fetch("/api/vehicles"),
|
||||
fetch("/api/units"),
|
||||
fetch("/api/fuel-personnel"),
|
||||
fetch("/api/goods-managers")
|
||||
fetch("/api/unit-personnel")
|
||||
]);
|
||||
|
||||
if (vehiclesRes.ok) {
|
||||
|
||||
@@ -44,10 +44,10 @@ let formData = {
|
||||
|
||||
async function loadGoodsManagers() {
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel');
|
||||
const response = await fetch('/api/unit-personnel');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
personnel = data.fuelPersonnel || [];
|
||||
personnel = data.goodsManagers || [];
|
||||
} else {
|
||||
error = 'Personel bilgileri yüklenemedi.';
|
||||
}
|
||||
@@ -77,15 +77,15 @@ function getUnitName(unitId) {
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formData = {
|
||||
full_name: '',
|
||||
rank: '',
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
formData = {
|
||||
full_name: '',
|
||||
rank: '',
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
selectedManager = null;
|
||||
}
|
||||
|
||||
@@ -96,15 +96,15 @@ function resetForm() {
|
||||
|
||||
function openEditModal(manager) {
|
||||
selectedManager = manager;
|
||||
formData = {
|
||||
full_name: manager.full_name,
|
||||
rank: manager.rank,
|
||||
registration_number: manager.registration_number,
|
||||
tc_kimlik: manager.tc_kimlik,
|
||||
phone: manager.phone,
|
||||
unit_id: manager.unit_id || '',
|
||||
is_active: manager.is_active
|
||||
};
|
||||
formData = {
|
||||
full_name: manager.full_name,
|
||||
rank: manager.rank,
|
||||
registration_number: manager.registration_number,
|
||||
tc_kimlik: manager.tc_kimlik,
|
||||
phone: manager.phone,
|
||||
unit_id: manager.unit_id || '',
|
||||
is_active: manager.is_active
|
||||
};
|
||||
showEditModal = true;
|
||||
}
|
||||
|
||||
@@ -120,13 +120,13 @@ async function handleAddManager() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/^[0-9]{11}$/.test(formData.tc_kimlik)) {
|
||||
error = 'TC Kimlik numarası 11 haneli olmalıdır.';
|
||||
return;
|
||||
}
|
||||
if (!/^[0-9]{11}$/.test(formData.tc_kimlik)) {
|
||||
error = 'TC Kimlik numarası 11 haneli olmalıdır.';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel', {
|
||||
const response = await fetch('/api/unit-personnel', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -155,13 +155,13 @@ async function handleUpdateManager() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/^[0-9]{11}$/.test(formData.tc_kimlik)) {
|
||||
error = 'TC Kimlik numarası 11 haneli olmalıdır.';
|
||||
return;
|
||||
}
|
||||
if (!/^[0-9]{11}$/.test(formData.tc_kimlik)) {
|
||||
error = 'TC Kimlik numarası 11 haneli olmalıdır.';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel', {
|
||||
const response = await fetch('/api/unit-personnel', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -193,7 +193,7 @@ async function handleUpdateManager() {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel', {
|
||||
const response = await fetch('/api/unit-personnel', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -217,7 +217,7 @@ async function handleUpdateManager() {
|
||||
|
||||
async function toggleManagerStatus(manager) {
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel', {
|
||||
const response = await fetch('/api/unit-personnel', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -895,6 +895,6 @@ async function handleUpdateManager() {
|
||||
|
||||
.detail-value {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
let user = null;
|
||||
let personnel = [];
|
||||
let units = [];
|
||||
let personnel = [];
|
||||
let loading = true;
|
||||
let error = '';
|
||||
let showAddModal = false;
|
||||
@@ -26,7 +25,6 @@
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
|
||||
@@ -38,25 +36,9 @@
|
||||
}
|
||||
|
||||
user = JSON.parse(userData);
|
||||
await loadUnits();
|
||||
await loadPersonnel();
|
||||
});
|
||||
|
||||
async function loadUnits() {
|
||||
try {
|
||||
const response = await fetch('/api/units');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
units = data.units;
|
||||
} else {
|
||||
error = 'Birlik listesi yüklenemedi.';
|
||||
}
|
||||
} catch (err) {
|
||||
error = 'Bağlantı hatası.';
|
||||
console.error('Load units error:', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPersonnel() {
|
||||
try {
|
||||
const response = await fetch('/api/fuel-personnel');
|
||||
@@ -81,7 +63,6 @@
|
||||
registration_number: '',
|
||||
tc_kimlik: '',
|
||||
phone: '',
|
||||
unit_id: '',
|
||||
is_active: true
|
||||
};
|
||||
selectedPersonnel = null;
|
||||
@@ -100,7 +81,6 @@
|
||||
registration_number: person.registration_number,
|
||||
tc_kimlik: person.tc_kimlik,
|
||||
phone: person.phone,
|
||||
unit_id: person.unit_id || '',
|
||||
is_active: person.is_active
|
||||
};
|
||||
showEditModal = true;
|
||||
@@ -113,7 +93,7 @@
|
||||
}
|
||||
|
||||
async function handleAddPersonnel() {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id) {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
@@ -148,7 +128,7 @@
|
||||
}
|
||||
|
||||
async function handleUpdatePersonnel() {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id) {
|
||||
if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
@@ -328,15 +308,24 @@
|
||||
<span class="detail-value">{person.tc_kimlik}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon">
|
||||
<i class="fas fa-phone"></i>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<span class="detail-label">İrtibat:</span>
|
||||
<span class="detail-value">{person.phone}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon">
|
||||
<i class="fas fa-phone"></i>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<span class="detail-label">İrtibat:</span>
|
||||
<span class="detail-value">{person.phone}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="detail-icon">
|
||||
<i class="fas fa-gas-pump"></i>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<span class="detail-label">Görev Yeri:</span>
|
||||
<span class="detail-value">Fuel Station</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="personnel-actions">
|
||||
@@ -445,20 +434,6 @@
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="unit_id">Birlik</label>
|
||||
<select
|
||||
id="unit_id"
|
||||
class="form-input"
|
||||
bind:value={formData.unit_id}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn btn-secondary" on:click={closeModal}>İptal</button>
|
||||
<button type="submit" class="btn btn-primary">Kaydet</button>
|
||||
@@ -533,20 +508,6 @@
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-unit_id">Birlik</label>
|
||||
<select
|
||||
id="edit-unit_id"
|
||||
class="form-input"
|
||||
bind:value={formData.unit_id}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="checkbox-label">
|
||||
<input
|
||||
@@ -931,4 +892,4 @@
|
||||
gap: 0.25rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
let user = null;
|
||||
let vehicles = [];
|
||||
let units = [];
|
||||
let loading = true;
|
||||
let error = '';
|
||||
let showAddModal = false;
|
||||
@@ -19,12 +20,13 @@
|
||||
let selectedVehicle = null;
|
||||
|
||||
// Form değişkenleri
|
||||
let formData = {
|
||||
brand: '',
|
||||
model: '',
|
||||
year: new Date().getFullYear(),
|
||||
plate: ''
|
||||
};
|
||||
let formData = {
|
||||
brand: '',
|
||||
model: '',
|
||||
year: new Date().getFullYear(),
|
||||
plate: '',
|
||||
unit_id: ''
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
const userData = localStorage.getItem('user');
|
||||
@@ -33,10 +35,31 @@
|
||||
return;
|
||||
}
|
||||
|
||||
user = JSON.parse(userData);
|
||||
await loadVehicles();
|
||||
user = JSON.parse(userData);
|
||||
await loadUnits();
|
||||
await loadVehicles();
|
||||
});
|
||||
|
||||
async function loadUnits() {
|
||||
try {
|
||||
const response = await fetch('/api/units');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
units = data.units || [];
|
||||
} else {
|
||||
error = 'Birlikler yüklenemedi.';
|
||||
}
|
||||
} catch (err) {
|
||||
error = 'Bağlantı hatası.';
|
||||
console.error('Load units error:', err);
|
||||
}
|
||||
}
|
||||
|
||||
function getUnitName(unitId, unitList = units) {
|
||||
const id = parseInt(unitId);
|
||||
return unitList.find((unit) => unit.id === id)?.name || 'Belirtilmemiş';
|
||||
}
|
||||
|
||||
async function loadVehicles() {
|
||||
try {
|
||||
const response = await fetch('/api/vehicles');
|
||||
@@ -55,12 +78,13 @@
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formData = {
|
||||
brand: '',
|
||||
model: '',
|
||||
year: new Date().getFullYear(),
|
||||
plate: ''
|
||||
};
|
||||
formData = {
|
||||
brand: '',
|
||||
model: '',
|
||||
year: new Date().getFullYear(),
|
||||
plate: '',
|
||||
unit_id: ''
|
||||
};
|
||||
selectedVehicle = null;
|
||||
}
|
||||
|
||||
@@ -71,12 +95,13 @@
|
||||
|
||||
function openEditModal(vehicle) {
|
||||
selectedVehicle = vehicle;
|
||||
formData = {
|
||||
brand: vehicle.brand,
|
||||
model: vehicle.model,
|
||||
year: vehicle.year,
|
||||
plate: vehicle.plate
|
||||
};
|
||||
formData = {
|
||||
brand: vehicle.brand,
|
||||
model: vehicle.model,
|
||||
year: vehicle.year,
|
||||
plate: vehicle.plate,
|
||||
unit_id: vehicle.unit_id ? vehicle.unit_id.toString() : ''
|
||||
};
|
||||
showEditModal = true;
|
||||
}
|
||||
|
||||
@@ -87,19 +112,23 @@
|
||||
}
|
||||
|
||||
async function handleAddVehicle() {
|
||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate) {
|
||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate || !formData.unit_id) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/vehicles', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
try {
|
||||
const payload = {
|
||||
...formData,
|
||||
unit_id: parseInt(formData.unit_id)
|
||||
};
|
||||
const response = await fetch('/api/vehicles', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
@@ -117,22 +146,24 @@
|
||||
}
|
||||
|
||||
async function handleUpdateVehicle() {
|
||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate) {
|
||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate || !formData.unit_id) {
|
||||
error = 'Tüm alanlar zorunludur.';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/vehicles', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: selectedVehicle.id,
|
||||
...formData
|
||||
}),
|
||||
});
|
||||
try {
|
||||
const payload = {
|
||||
id: selectedVehicle.id,
|
||||
...formData,
|
||||
unit_id: parseInt(formData.unit_id)
|
||||
};
|
||||
const response = await fetch('/api/vehicles', {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
@@ -242,6 +273,9 @@
|
||||
<span class="plate-badge"><i class="fas fa-car"></i> {vehicle.plate}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="vehicle-unit">
|
||||
<i class="fas fa-building"></i> {vehicle.unit_name || getUnitName(vehicle.unit_id, units)}
|
||||
</p>
|
||||
<div class="vehicle-actions">
|
||||
<button class="btn btn-sm btn-secondary" on:click={() => openEditModal(vehicle)}>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
@@ -318,6 +352,20 @@
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="unit_id">Birlik</label>
|
||||
<select
|
||||
id="unit_id"
|
||||
class="form-input"
|
||||
bind:value={formData.unit_id}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn btn-secondary" on:click={closeModal}>İptal</button>
|
||||
<button type="submit" class="btn btn-primary">Kaydet</button>
|
||||
@@ -381,6 +429,20 @@
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-unit_id">Birlik</label>
|
||||
<select
|
||||
id="edit-unit_id"
|
||||
class="form-input"
|
||||
bind:value={formData.unit_id}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn btn-secondary" on:click={closeModal}>İptal</button>
|
||||
<button type="submit" class="btn btn-primary">Güncelle</button>
|
||||
@@ -501,6 +563,15 @@
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.vehicle-unit {
|
||||
margin: 0 0 1rem;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.vehicle-info h3 {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
@@ -657,4 +728,4 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
let personnel = [];
|
||||
let fuelSlips = [];
|
||||
let approvedRejectedSlips = [];
|
||||
let goodsManagers = [];
|
||||
let receivingPersonnel = [];
|
||||
let filteredReceivingPersonnel = [];
|
||||
let loading = true;
|
||||
let error = '';
|
||||
let showCreateModal = false;
|
||||
@@ -37,7 +38,7 @@
|
||||
liters: '',
|
||||
km: '',
|
||||
personnel_id: '',
|
||||
goods_manager_id: 2, // Varsayılan mal sorumlusu
|
||||
goods_manager_id: '',
|
||||
notes: ''
|
||||
};
|
||||
|
||||
@@ -77,12 +78,12 @@
|
||||
async function loadData() {
|
||||
try {
|
||||
// Paralel veri yükleme
|
||||
const [vehiclesRes, unitsRes, personnelRes, slipsRes, goodsManagersRes] = await Promise.all([
|
||||
const [vehiclesRes, unitsRes, personnelRes, slipsRes, unitPersonnelRes] = await Promise.all([
|
||||
fetch('/api/vehicles'),
|
||||
fetch('/api/units'),
|
||||
fetch('/api/fuel-personnel'),
|
||||
fetch('/api/fuel-slips'),
|
||||
fetch('/api/goods-managers')
|
||||
fetch('/api/unit-personnel')
|
||||
]);
|
||||
|
||||
if (vehiclesRes.ok) {
|
||||
@@ -117,9 +118,10 @@
|
||||
});
|
||||
}
|
||||
|
||||
if (goodsManagersRes.ok) {
|
||||
const goodsData = await goodsManagersRes.json();
|
||||
goodsManagers = goodsData.goodsManagers?.filter(gm => gm.is_active) || [];
|
||||
if (unitPersonnelRes.ok) {
|
||||
const receiversData = await unitPersonnelRes.json();
|
||||
receivingPersonnel = receiversData.unitPersonnel?.filter(person => person.is_active) || [];
|
||||
syncReceiverSelection();
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
@@ -130,6 +132,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
function getUnitPersonnelByUnit(unitId) {
|
||||
if (!unitId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const normalizedUnit = parseInt(unitId);
|
||||
return receivingPersonnel.filter(person => person.unit_id === normalizedUnit);
|
||||
}
|
||||
|
||||
function syncReceiverSelection(unitId = formData.unit_id) {
|
||||
const candidates = getUnitPersonnelByUnit(unitId);
|
||||
filteredReceivingPersonnel = candidates;
|
||||
|
||||
if (!unitId) {
|
||||
formData.goods_manager_id = '';
|
||||
return;
|
||||
}
|
||||
|
||||
if (candidates.length === 0) {
|
||||
formData.goods_manager_id = '';
|
||||
return;
|
||||
}
|
||||
|
||||
const hasCurrent = candidates.some(person => person.id.toString() === formData.goods_manager_id?.toString());
|
||||
if (!hasCurrent) {
|
||||
formData.goods_manager_id = candidates[0].id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
function handleUnitChange(event) {
|
||||
const value = event.target.value;
|
||||
formData.unit_id = value;
|
||||
syncReceiverSelection(value);
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formData = {
|
||||
date: new Date().toISOString().split('T')[0],
|
||||
@@ -140,9 +177,10 @@
|
||||
liters: '',
|
||||
km: '',
|
||||
personnel_id: '',
|
||||
goods_manager_id: goodsManagers.length > 0 ? goodsManagers[0].id : '',
|
||||
goods_manager_id: '',
|
||||
notes: ''
|
||||
};
|
||||
syncReceiverSelection('');
|
||||
}
|
||||
|
||||
function openCreateModal() {
|
||||
@@ -378,7 +416,13 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="unit_id">Birlik</label>
|
||||
<select id="unit_id" class="form-select" bind:value={formData.unit_id} required>
|
||||
<select
|
||||
id="unit_id"
|
||||
class="form-select"
|
||||
bind:value={formData.unit_id}
|
||||
on:change={handleUnitChange}
|
||||
required
|
||||
>
|
||||
<option value="">Birlik Seçin</option>
|
||||
{#each units as unit}
|
||||
<option value={unit.id}>{unit.name}</option>
|
||||
@@ -437,10 +481,20 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="goods_manager_id">Teslim Alan</label>
|
||||
<select id="goods_manager_id" class="form-select" bind:value={formData.goods_manager_id} required>
|
||||
<option value="">Mal Sorumlusu Seçin</option>
|
||||
{#each goodsManagers as manager}
|
||||
<option value={manager.id}>{manager.rank} {manager.full_name}</option>
|
||||
<select
|
||||
id="goods_manager_id"
|
||||
class="form-select"
|
||||
bind:value={formData.goods_manager_id}
|
||||
disabled={!formData.unit_id || filteredReceivingPersonnel.length === 0}
|
||||
required
|
||||
>
|
||||
{#if !formData.unit_id}
|
||||
<option value="">Önce birlik seçin</option>
|
||||
{:else if filteredReceivingPersonnel.length === 0}
|
||||
<option value="">Bu birliğe kayıtlı personel yok</option>
|
||||
{/if}
|
||||
{#each filteredReceivingPersonnel as person}
|
||||
<option value={person.id}>{person.rank} {person.full_name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
@@ -1042,4 +1096,4 @@
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
434
src/server.js
434
src/server.js
@@ -11,7 +11,8 @@ import {
|
||||
getGoodsManagers,
|
||||
addGoodsManager,
|
||||
updateGoodsManager,
|
||||
deleteGoodsManager
|
||||
deleteGoodsManager,
|
||||
findGoodsManagerById
|
||||
} from './lib/data/goodsManagers.js';
|
||||
|
||||
// Units veritabanı
|
||||
@@ -65,6 +66,19 @@ let units = [
|
||||
|
||||
let nextUnitId = 4;
|
||||
|
||||
const getUnitById = (unitId) => {
|
||||
if (unitId === null || unitId === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const id = parseInt(unitId);
|
||||
return units.find((unit) => unit.id === id) || null;
|
||||
};
|
||||
|
||||
const getUnitNameById = (unitId) => {
|
||||
return getUnitById(unitId)?.name || 'Belirtilmemiş';
|
||||
};
|
||||
|
||||
// Vehicles veritabanı
|
||||
let vehicles = [
|
||||
{
|
||||
@@ -73,6 +87,7 @@ let vehicles = [
|
||||
model: 'Actros 1851',
|
||||
year: 2020,
|
||||
plate: '34 ABC 123',
|
||||
unit_id: 1,
|
||||
fuel_type: 'Dizel',
|
||||
fuel_capacity: 500,
|
||||
current_fuel: 300,
|
||||
@@ -87,6 +102,7 @@ let vehicles = [
|
||||
model: 'FH16 750',
|
||||
year: 2021,
|
||||
plate: '34 XYZ 789',
|
||||
unit_id: 2,
|
||||
fuel_type: 'Dizel',
|
||||
fuel_capacity: 600,
|
||||
current_fuel: 450,
|
||||
@@ -101,6 +117,7 @@ let vehicles = [
|
||||
model: 'R730',
|
||||
year: 2019,
|
||||
plate: '34 DEF 456',
|
||||
unit_id: 3,
|
||||
fuel_type: 'Dizel',
|
||||
fuel_capacity: 550,
|
||||
current_fuel: 200,
|
||||
@@ -111,6 +128,11 @@ let vehicles = [
|
||||
}
|
||||
];
|
||||
|
||||
vehicles = vehicles.map((vehicle) => ({
|
||||
...vehicle,
|
||||
unit_name: getUnitNameById(vehicle.unit_id)
|
||||
}));
|
||||
|
||||
let nextVehicleId = 4;
|
||||
|
||||
// Fuel Personnel veritabanı
|
||||
@@ -119,7 +141,7 @@ let fuelPersonnel = [
|
||||
id: 1,
|
||||
full_name: 'Ahmet Demir',
|
||||
rank: 'Üsteğmen',
|
||||
registration_number: '111222',
|
||||
registration_number: 'FP-111222',
|
||||
tc_kimlik: '11111111111',
|
||||
phone: '05321112233',
|
||||
is_active: true,
|
||||
@@ -129,7 +151,7 @@ let fuelPersonnel = [
|
||||
id: 2,
|
||||
full_name: 'Mustafa Çelik',
|
||||
rank: 'Astsubay',
|
||||
registration_number: '333444',
|
||||
registration_number: 'FP-333444',
|
||||
tc_kimlik: '22222222222',
|
||||
phone: '05334455566',
|
||||
is_active: true,
|
||||
@@ -139,6 +161,59 @@ let fuelPersonnel = [
|
||||
|
||||
let nextFuelPersonnelId = 3;
|
||||
|
||||
// Unit personnel listesi (teslim alanlar)
|
||||
let unitPersonnel = [
|
||||
{
|
||||
id: 1,
|
||||
full_name: 'Serkan Yılmaz',
|
||||
rank: 'Teğmen',
|
||||
registration_number: 'UP-1001',
|
||||
tc_kimlik: '12312312312',
|
||||
phone: '05320001122',
|
||||
unit_id: 1,
|
||||
is_active: true,
|
||||
created_at: new Date().toISOString()
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
full_name: 'Barış Aksoy',
|
||||
rank: 'Astsubay',
|
||||
registration_number: 'UP-2001',
|
||||
tc_kimlik: '98798798798',
|
||||
phone: '05323334455',
|
||||
unit_id: 2,
|
||||
is_active: true,
|
||||
created_at: new Date().toISOString()
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
full_name: 'Hakan Güler',
|
||||
rank: 'Üstçavuş',
|
||||
registration_number: 'UP-3001',
|
||||
tc_kimlik: '55544433322',
|
||||
phone: '05324445566',
|
||||
unit_id: 3,
|
||||
is_active: true,
|
||||
created_at: new Date().toISOString()
|
||||
}
|
||||
];
|
||||
|
||||
let nextUnitPersonnelId = 4;
|
||||
|
||||
|
||||
function parseMukannenValue(value) {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
return value;
|
||||
}
|
||||
|
||||
const parsed = parseFloat(value.toString().replace(',', '.'));
|
||||
return isNaN(parsed) ? 0 : parsed;
|
||||
}
|
||||
|
||||
const app = express();
|
||||
const server = createServer(app);
|
||||
const io = new Server(server, {
|
||||
@@ -746,14 +821,144 @@ app.delete('/api/goods-managers', async (req, res) => {
|
||||
|
||||
// GET - Tüm yakıt personelini listele
|
||||
app.get('/api/fuel-personnel', (req, res) => {
|
||||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||||
res.json({ fuelPersonnel });
|
||||
});
|
||||
|
||||
// POST - Yeni yakıt personeli ekle
|
||||
app.post('/api/fuel-personnel', async (req, res) => {
|
||||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||||
try {
|
||||
const {
|
||||
full_name,
|
||||
rank,
|
||||
registration_number,
|
||||
tc_kimlik,
|
||||
phone,
|
||||
is_active = true
|
||||
} = req.body;
|
||||
|
||||
if (!full_name || !rank || !registration_number || !tc_kimlik || !phone) {
|
||||
return res.status(400).json({ message: 'Tüm alanlar zorunludur.' });
|
||||
}
|
||||
|
||||
if (!/^[0-9]{11}$/.test(tc_kimlik)) {
|
||||
return res.status(400).json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' });
|
||||
}
|
||||
|
||||
const existingPersonnel = fuelPersonnel.find(p =>
|
||||
p.registration_number === registration_number || p.tc_kimlik === tc_kimlik
|
||||
);
|
||||
if (existingPersonnel) {
|
||||
return res.status(400).json({ message: 'Bu personel zaten kayıtlı.' });
|
||||
}
|
||||
|
||||
const newPersonnel = {
|
||||
id: nextFuelPersonnelId++,
|
||||
full_name: full_name.trim(),
|
||||
rank: rank.trim(),
|
||||
registration_number: registration_number.trim(),
|
||||
tc_kimlik: tc_kimlik.trim(),
|
||||
phone: phone.trim(),
|
||||
is_active: Boolean(is_active),
|
||||
created_at: new Date().toISOString()
|
||||
};
|
||||
|
||||
fuelPersonnel.push(newPersonnel);
|
||||
|
||||
res.json({
|
||||
message: 'Yakıt personeli başarıyla eklendi.',
|
||||
fuelPersonnel: newPersonnel
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: 'Sunucu hatası.' });
|
||||
}
|
||||
});
|
||||
|
||||
// PUT - Yakıt personeli güncelle
|
||||
app.put('/api/fuel-personnel', (req, res) => {
|
||||
try {
|
||||
const {
|
||||
id,
|
||||
full_name,
|
||||
rank,
|
||||
registration_number,
|
||||
tc_kimlik,
|
||||
phone,
|
||||
is_active
|
||||
} = req.body;
|
||||
|
||||
if (!id || !full_name || !rank || !registration_number || !tc_kimlik || !phone) {
|
||||
return res.status(400).json({ message: 'Tüm alanlar zorunludur.' });
|
||||
}
|
||||
|
||||
if (!/^[0-9]{11}$/.test(tc_kimlik)) {
|
||||
return res.status(400).json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' });
|
||||
}
|
||||
|
||||
const personnelIndex = fuelPersonnel.findIndex(p => p.id === parseInt(id));
|
||||
if (personnelIndex === -1) {
|
||||
return res.status(404).json({ message: 'Personel bulunamadı.' });
|
||||
}
|
||||
|
||||
const duplicate = fuelPersonnel.find(p =>
|
||||
p.id !== parseInt(id) && (p.registration_number === registration_number || p.tc_kimlik === tc_kimlik)
|
||||
);
|
||||
if (duplicate) {
|
||||
return res.status(400).json({ message: 'Aynı sicil veya TC Kimlik başka bir personelde mevcut.' });
|
||||
}
|
||||
|
||||
fuelPersonnel[personnelIndex] = {
|
||||
...fuelPersonnel[personnelIndex],
|
||||
full_name: full_name.trim(),
|
||||
rank: rank.trim(),
|
||||
registration_number: registration_number.trim(),
|
||||
tc_kimlik: tc_kimlik.trim(),
|
||||
phone: phone.trim(),
|
||||
is_active: Boolean(is_active)
|
||||
};
|
||||
|
||||
res.json({
|
||||
message: 'Yakıt personeli güncellendi.',
|
||||
fuelPersonnel: fuelPersonnel[personnelIndex]
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: 'Sunucu hatası.' });
|
||||
}
|
||||
});
|
||||
|
||||
// DELETE - Yakıt personeli sil
|
||||
app.delete('/api/fuel-personnel', (req, res) => {
|
||||
try {
|
||||
const { id } = req.body;
|
||||
|
||||
if (!id) {
|
||||
return res.status(400).json({ message: 'Personel ID zorunludur.' });
|
||||
}
|
||||
|
||||
const personnelIndex = fuelPersonnel.findIndex(p => p.id === parseInt(id));
|
||||
if (personnelIndex === -1) {
|
||||
return res.status(404).json({ message: 'Personel bulunamadı.' });
|
||||
}
|
||||
|
||||
const deletedPersonnel = fuelPersonnel.splice(personnelIndex, 1)[0];
|
||||
|
||||
res.json({
|
||||
message: 'Yakıt personeli silindi.',
|
||||
fuelPersonnel: deletedPersonnel
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: 'Sunucu hatası.' });
|
||||
}
|
||||
});
|
||||
|
||||
// Unit Personnel API endpoint'leri (Teslim Alan personeller)
|
||||
app.get('/api/unit-personnel', (req, res) => {
|
||||
res.json({ unitPersonnel });
|
||||
});
|
||||
|
||||
app.post('/api/unit-personnel', (req, res) => {
|
||||
try {
|
||||
const {
|
||||
full_name,
|
||||
@@ -765,35 +970,23 @@ app.post('/api/fuel-personnel', async (req, res) => {
|
||||
is_active = true
|
||||
} = req.body;
|
||||
|
||||
// Validasyon
|
||||
if (!full_name || !rank || !registration_number || !tc_kimlik || !phone || !unit_id) {
|
||||
return res.status(400).json({ message: 'Tüm alanlar zorunludur.' });
|
||||
}
|
||||
|
||||
// TC Kimlik numarası validasyonu
|
||||
if (!/^[0-9]{11}$/.test(tc_kimlik)) {
|
||||
return res.status(400).json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' });
|
||||
}
|
||||
|
||||
// Sicil numarası tekrar kontrolü
|
||||
const existingPersonnel = fuelPersonnel.find(p =>
|
||||
p.registration_number === registration_number
|
||||
const duplicate = unitPersonnel.find(p =>
|
||||
p.registration_number === registration_number || p.tc_kimlik === tc_kimlik
|
||||
);
|
||||
if (existingPersonnel) {
|
||||
return res.status(400).json({ message: 'Bu sicil numarası zaten kayıtlı.' });
|
||||
if (duplicate) {
|
||||
return res.status(400).json({ message: 'Bu personel zaten kayıtlı.' });
|
||||
}
|
||||
|
||||
// TC Kimlik numarası tekrar kontrolü
|
||||
const existingTc = fuelPersonnel.find(p =>
|
||||
p.tc_kimlik === tc_kimlik
|
||||
);
|
||||
if (existingTc) {
|
||||
return res.status(400).json({ message: 'Bu TC Kimlik numarası zaten kayıtlı.' });
|
||||
}
|
||||
|
||||
// Yeni personel oluştur
|
||||
const newPersonnel = {
|
||||
id: nextFuelPersonnelId++,
|
||||
id: nextUnitPersonnelId++,
|
||||
full_name: full_name.trim(),
|
||||
rank: rank.trim(),
|
||||
registration_number: registration_number.trim(),
|
||||
@@ -804,46 +997,11 @@ app.post('/api/fuel-personnel', async (req, res) => {
|
||||
created_at: new Date().toISOString()
|
||||
};
|
||||
|
||||
// Birlik personeli için kullanıcı oluştur
|
||||
try {
|
||||
// Kullanıcı adını TC kimlik numarasından oluştur
|
||||
const username = `bp_${tc_kimlik}`;
|
||||
const defaultPassword = tc_kimlik.substring(0, 6); // İlk 6 hane varsayılan şifre
|
||||
|
||||
const hashedPassword = await bcrypt.hash(defaultPassword, 10);
|
||||
|
||||
// Kullanıcı adı benzersizliğini kontrol et
|
||||
const existingUser = await new Promise((resolve, reject) => {
|
||||
db.get('SELECT id FROM users WHERE username = ?', [username], (err, row) => {
|
||||
if (err) reject(err);
|
||||
else resolve(row);
|
||||
});
|
||||
});
|
||||
|
||||
if (existingUser) {
|
||||
return res.status(400).json({ message: 'Bu personel için zaten kullanıcı hesabı mevcut.' });
|
||||
}
|
||||
|
||||
// Birlik personeli olarak kullanıcı ekle
|
||||
await new Promise((resolve, reject) => {
|
||||
db.run('INSERT INTO users (username, password, role, full_name) VALUES (?, ?, ?, ?)',
|
||||
[username, hashedPassword, 'birlik_personeli', full_name], (err) => {
|
||||
if (err) reject(err);
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
|
||||
console.log(`✅ Birlik personeli kullanıcı oluşturuldu: ${username}`);
|
||||
} catch (userError) {
|
||||
console.error('❌ Birlik personeli kullanıcı oluşturma hatası:', userError);
|
||||
return res.status(500).json({ message: 'Personel için kullanıcı hesabı oluşturulamadı.' });
|
||||
}
|
||||
|
||||
fuelPersonnel.push(newPersonnel);
|
||||
unitPersonnel.push(newPersonnel);
|
||||
|
||||
res.json({
|
||||
message: 'Personel başarıyla eklendi.',
|
||||
fuelPersonnel: newPersonnel
|
||||
personnel: newPersonnel
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
@@ -851,10 +1009,7 @@ app.post('/api/fuel-personnel', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// PUT - Yakıt personeli güncelle
|
||||
app.put('/api/fuel-personnel', (req, res) => {
|
||||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||||
|
||||
app.put('/api/unit-personnel', (req, res) => {
|
||||
try {
|
||||
const {
|
||||
id,
|
||||
@@ -867,41 +1022,28 @@ app.put('/api/fuel-personnel', (req, res) => {
|
||||
is_active
|
||||
} = req.body;
|
||||
|
||||
// Validasyon
|
||||
if (!id || !full_name || !rank || !registration_number || !tc_kimlik || !phone || !unit_id) {
|
||||
return res.status(400).json({ message: 'Tüm alanlar zorunludur.' });
|
||||
}
|
||||
|
||||
// TC Kimlik numarası validasyonu
|
||||
if (!/^[0-9]{11}$/.test(tc_kimlik)) {
|
||||
return res.status(400).json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' });
|
||||
}
|
||||
|
||||
// Personel bul
|
||||
const personnelIndex = fuelPersonnel.findIndex(p => p.id === parseInt(id));
|
||||
const personnelIndex = unitPersonnel.findIndex(p => p.id === parseInt(id));
|
||||
if (personnelIndex === -1) {
|
||||
return res.status(404).json({ message: 'Personel bulunamadı.' });
|
||||
}
|
||||
|
||||
// Sicil numarası tekrar kontrolü (başka personel için)
|
||||
const existingRegNumber = fuelPersonnel.find(p =>
|
||||
p.id !== parseInt(id) && p.registration_number === registration_number
|
||||
const duplicate = unitPersonnel.find(p =>
|
||||
p.id !== parseInt(id) && (p.registration_number === registration_number || p.tc_kimlik === tc_kimlik)
|
||||
);
|
||||
if (existingRegNumber) {
|
||||
return res.status(400).json({ message: 'Bu sicil numarası başka bir personelde kayıtlı.' });
|
||||
if (duplicate) {
|
||||
return res.status(400).json({ message: 'Bu sicil veya TC Kimlik başka bir personelde mevcut.' });
|
||||
}
|
||||
|
||||
// TC Kimlik numarası tekrar kontrolü (başka personel için)
|
||||
const existingTc = fuelPersonnel.find(p =>
|
||||
p.id !== parseInt(id) && p.tc_kimlik === tc_kimlik
|
||||
);
|
||||
if (existingTc) {
|
||||
return res.status(400).json({ message: 'Bu TC Kimlik numarası başka bir personelde kayıtlı.' });
|
||||
}
|
||||
|
||||
// Personeli güncelle
|
||||
fuelPersonnel[personnelIndex] = {
|
||||
...fuelPersonnel[personnelIndex],
|
||||
unitPersonnel[personnelIndex] = {
|
||||
...unitPersonnel[personnelIndex],
|
||||
full_name: full_name.trim(),
|
||||
rank: rank.trim(),
|
||||
registration_number: registration_number.trim(),
|
||||
@@ -912,8 +1054,8 @@ app.put('/api/fuel-personnel', (req, res) => {
|
||||
};
|
||||
|
||||
res.json({
|
||||
message: 'Personel başarıyla güncellendi.',
|
||||
fuelPersonnel: fuelPersonnel[personnelIndex]
|
||||
message: 'Personel güncellendi.',
|
||||
personnel: unitPersonnel[personnelIndex]
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
@@ -921,10 +1063,7 @@ app.put('/api/fuel-personnel', (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// DELETE - Yakıt personeli sil
|
||||
app.delete('/api/fuel-personnel', (req, res) => {
|
||||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||||
|
||||
app.delete('/api/unit-personnel', (req, res) => {
|
||||
try {
|
||||
const { id } = req.body;
|
||||
|
||||
@@ -932,18 +1071,16 @@ app.delete('/api/fuel-personnel', (req, res) => {
|
||||
return res.status(400).json({ message: 'Personel ID zorunludur.' });
|
||||
}
|
||||
|
||||
// Personel bul
|
||||
const personnelIndex = fuelPersonnel.findIndex(p => p.id === parseInt(id));
|
||||
const personnelIndex = unitPersonnel.findIndex(p => p.id === parseInt(id));
|
||||
if (personnelIndex === -1) {
|
||||
return res.status(404).json({ message: 'Personel bulunamadı.' });
|
||||
}
|
||||
|
||||
// Personel sil
|
||||
const deletedPersonnel = fuelPersonnel.splice(personnelIndex, 1)[0];
|
||||
const deletedPersonnel = unitPersonnel.splice(personnelIndex, 1)[0];
|
||||
|
||||
res.json({
|
||||
message: 'Personel başarıyla silindi.',
|
||||
fuelPersonnel: deletedPersonnel
|
||||
message: 'Personel silindi.',
|
||||
personnel: deletedPersonnel
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
@@ -951,6 +1088,7 @@ app.delete('/api/fuel-personnel', (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Fuel Slips API endpoint'leri
|
||||
|
||||
// GET - Yakıt fişlerini listele
|
||||
@@ -1028,21 +1166,29 @@ app.post('/api/fuel-slips', async (req, res) => {
|
||||
return res.status(400).json({ message: 'Litre ve KM değerleri geçersiz.' });
|
||||
}
|
||||
|
||||
const unitId = parseInt(slipData.unit_id);
|
||||
const vehicleId = parseInt(slipData.vehicle_id);
|
||||
const personnelId = parseInt(slipData.personnel_id);
|
||||
const goodsManagerId = parseInt(slipData.goods_manager_id);
|
||||
const fuelManagerId = parseInt(slipData.fuel_manager_id);
|
||||
|
||||
// Araç, personel ve mal sorumlusu bilgilerini getir
|
||||
const [vehicle, unit, person, goodsManager] = await Promise.all([
|
||||
vehicles.find(v => v.id === parseInt(slipData.vehicle_id)),
|
||||
units.find(u => u.id === parseInt(slipData.unit_id)),
|
||||
Promise.resolve({ // Temporary fuel personnel lookup
|
||||
id: 1,
|
||||
full_name: 'Ahmet Demir',
|
||||
rank: 'Üsteğmen'
|
||||
}),
|
||||
Promise.resolve({ // Temporary goods manager lookup
|
||||
id: slipData.goods_manager_id,
|
||||
full_name: 'Mal Sorumlusu',
|
||||
rank: 'Yüzbaşı'
|
||||
})
|
||||
]);
|
||||
const vehicle = vehicles.find(v => v.id === vehicleId);
|
||||
const unit = units.find(u => u.id === unitId);
|
||||
const person = fuelPersonnel.find(p => p.id === personnelId && p.is_active);
|
||||
const receivingPerson = unitPersonnel.find(p => p.id === goodsManagerId && p.is_active);
|
||||
|
||||
if (!person) {
|
||||
return res.status(400).json({ message: 'Teslim eden personel bulunamadı veya pasif durumda.' });
|
||||
}
|
||||
|
||||
if (!receivingPerson) {
|
||||
return res.status(400).json({ message: 'Teslim alan personel bulunamadı veya pasif durumda.' });
|
||||
}
|
||||
|
||||
if (receivingPerson.unit_id !== unitId) {
|
||||
return res.status(400).json({ message: 'Seçilen personel bu birliğe bağlı değil.' });
|
||||
}
|
||||
|
||||
const vehicleInfo = vehicle ? {
|
||||
brand: vehicle.brand,
|
||||
@@ -1058,15 +1204,19 @@ app.post('/api/fuel-slips', async (req, res) => {
|
||||
|
||||
const personnelInfo = person ? {
|
||||
full_name: person.full_name,
|
||||
rank: person.rank
|
||||
rank: person.rank,
|
||||
unit_id: person.unit_id,
|
||||
registration_number: person.registration_number
|
||||
} : {
|
||||
full_name: 'Bilinmeyen Personel',
|
||||
rank: ''
|
||||
};
|
||||
|
||||
const goodsManagerInfo = goodsManager ? {
|
||||
full_name: goodsManager.full_name,
|
||||
rank: goodsManager.rank
|
||||
const goodsManagerInfo = receivingPerson ? {
|
||||
full_name: receivingPerson.full_name,
|
||||
rank: receivingPerson.rank,
|
||||
unit_id: receivingPerson.unit_id,
|
||||
unit_name: getUnitNameById(receivingPerson.unit_id)
|
||||
} : {
|
||||
full_name: 'Bilinmeyen Mal Sorumlusu',
|
||||
rank: ''
|
||||
@@ -1085,18 +1235,18 @@ app.post('/api/fuel-slips', async (req, res) => {
|
||||
const params = [
|
||||
slipData.date,
|
||||
slipData.force_command,
|
||||
slipData.unit_id,
|
||||
unit?.name || `Birim ${slipData.unit_id}`,
|
||||
slipData.vehicle_id,
|
||||
unitId,
|
||||
unit?.name || `Birim ${unitId}`,
|
||||
vehicleId,
|
||||
JSON.stringify(vehicleInfo),
|
||||
slipData.fuel_type,
|
||||
parseFloat(slipData.liters),
|
||||
parseInt(slipData.km),
|
||||
slipData.personnel_id,
|
||||
personnelId,
|
||||
JSON.stringify(personnelInfo),
|
||||
slipData.goods_manager_id,
|
||||
goodsManagerId,
|
||||
JSON.stringify(goodsManagerInfo),
|
||||
slipData.fuel_manager_id,
|
||||
fuelManagerId,
|
||||
JSON.stringify(fuelManagerInfo),
|
||||
'pending',
|
||||
slipData.notes || ''
|
||||
@@ -1112,18 +1262,18 @@ app.post('/api/fuel-slips', async (req, res) => {
|
||||
id: this.lastID,
|
||||
date: slipData.date,
|
||||
force_command: slipData.force_command,
|
||||
unit_id: slipData.unit_id,
|
||||
unit_name: unit?.name || `Birim ${slipData.unit_id}`,
|
||||
vehicle_id: slipData.vehicle_id,
|
||||
unit_id: unitId,
|
||||
unit_name: unit?.name || `Birim ${unitId}`,
|
||||
vehicle_id: vehicleId,
|
||||
vehicle_info: vehicleInfo,
|
||||
fuel_type: slipData.fuel_type,
|
||||
liters: parseFloat(slipData.liters),
|
||||
km: parseInt(slipData.km),
|
||||
personnel_id: slipData.personnel_id,
|
||||
personnel_id: personnelId,
|
||||
personnel_info: personnelInfo,
|
||||
goods_manager_id: slipData.goods_manager_id,
|
||||
goods_manager_id: goodsManagerId,
|
||||
goods_manager_info: goodsManagerInfo,
|
||||
fuel_manager_id: slipData.fuel_manager_id,
|
||||
fuel_manager_id: fuelManagerId,
|
||||
fuel_manager_info: fuelManagerInfo,
|
||||
status: 'pending',
|
||||
notes: slipData.notes || '',
|
||||
@@ -1297,6 +1447,7 @@ app.post('/api/vehicles', (req, res) => {
|
||||
model,
|
||||
year,
|
||||
plate,
|
||||
unit_id,
|
||||
fuel_type,
|
||||
fuel_capacity,
|
||||
current_fuel,
|
||||
@@ -1308,10 +1459,15 @@ app.post('/api/vehicles', (req, res) => {
|
||||
} = req.body;
|
||||
|
||||
// Validasyon
|
||||
if (!brand || !model || !year || !plate || !fuel_type || !fuel_capacity) {
|
||||
if (!brand || !model || !year || !plate || !unit_id || !fuel_type || !fuel_capacity) {
|
||||
return res.status(400).json({ message: 'Tüm zorunlu alanları doldurun.' });
|
||||
}
|
||||
|
||||
const targetUnit = units.find(u => u.id === parseInt(unit_id));
|
||||
if (!targetUnit) {
|
||||
return res.status(400).json({ message: 'Geçerli bir birlik seçin.' });
|
||||
}
|
||||
|
||||
if (year < 1990 || year > new Date().getFullYear() + 1) {
|
||||
return res.status(400).json({ message: 'Geçerli bir yıl girin.' });
|
||||
}
|
||||
@@ -1329,18 +1485,21 @@ app.post('/api/vehicles', (req, res) => {
|
||||
}
|
||||
|
||||
// Yeni araç oluştur
|
||||
const unitName = targetUnit.name;
|
||||
const newVehicle = {
|
||||
id: nextVehicleId++,
|
||||
brand: brand.trim(),
|
||||
model: model.trim(),
|
||||
year: parseInt(year),
|
||||
plate: plate.trim().toUpperCase(),
|
||||
unit_id: parseInt(unit_id),
|
||||
fuel_type: fuel_type.trim(),
|
||||
fuel_capacity: parseInt(fuel_capacity),
|
||||
current_fuel: parseInt(current_fuel) || 0,
|
||||
yazlik_mukannen: parseInt(yazlik_mukannen) || 0,
|
||||
kislik_mukannen: parseInt(kislik_mukannen) || 0,
|
||||
status: status.trim(),
|
||||
yazlik_mukannen: parseMukannenValue(yazlik_mukannen),
|
||||
kislik_mukannen: parseMukannenValue(kislik_mukannen),
|
||||
status: (status || 'Aktif').trim(),
|
||||
unit_name: unitName,
|
||||
driver_id: driver_id ? parseInt(driver_id) : null,
|
||||
driver_name: driver_name ? driver_name.trim() : null,
|
||||
created_at: new Date().toISOString()
|
||||
@@ -1369,6 +1528,7 @@ app.put('/api/vehicles', (req, res) => {
|
||||
model,
|
||||
year,
|
||||
plate,
|
||||
unit_id,
|
||||
fuel_type,
|
||||
fuel_capacity,
|
||||
current_fuel,
|
||||
@@ -1380,10 +1540,15 @@ app.put('/api/vehicles', (req, res) => {
|
||||
} = req.body;
|
||||
|
||||
// Validasyon
|
||||
if (!id || !brand || !model || !year || !plate || !fuel_type || !fuel_capacity) {
|
||||
if (!id || !brand || !model || !year || !plate || !unit_id || !fuel_type || !fuel_capacity) {
|
||||
return res.status(400).json({ message: 'Tüm zorunlu alanları doldurun.' });
|
||||
}
|
||||
|
||||
const targetUnit = units.find(u => u.id === parseInt(unit_id));
|
||||
if (!targetUnit) {
|
||||
return res.status(400).json({ message: 'Geçerli bir birlik seçin.' });
|
||||
}
|
||||
|
||||
if (year < 1990 || year > new Date().getFullYear() + 1) {
|
||||
return res.status(400).json({ message: 'Geçerli bir yıl girin.' });
|
||||
}
|
||||
@@ -1407,18 +1572,21 @@ app.put('/api/vehicles', (req, res) => {
|
||||
}
|
||||
|
||||
// Araç güncelle
|
||||
const unitName = targetUnit.name;
|
||||
vehicles[vehicleIndex] = {
|
||||
...vehicles[vehicleIndex],
|
||||
brand: brand.trim(),
|
||||
model: model.trim(),
|
||||
year: parseInt(year),
|
||||
plate: plate.trim().toUpperCase(),
|
||||
unit_id: parseInt(unit_id),
|
||||
fuel_type: fuel_type.trim(),
|
||||
fuel_capacity: parseInt(fuel_capacity),
|
||||
current_fuel: parseInt(current_fuel) || 0,
|
||||
yazlik_mukannen: parseInt(yazlik_mukannen) || 0,
|
||||
kislik_mukannen: parseInt(kislik_mukannen) || 0,
|
||||
yazlik_mukannen: parseMukannenValue(yazlik_mukannen),
|
||||
kislik_mukannen: parseMukannenValue(kislik_mukannen),
|
||||
status: (status || 'Aktif').trim(),
|
||||
unit_name: unitName,
|
||||
driver_id: driver_id ? parseInt(driver_id) : null,
|
||||
driver_name: driver_name ? driver_name.trim() : null
|
||||
};
|
||||
@@ -1516,4 +1684,4 @@ async function startServer() {
|
||||
}
|
||||
}
|
||||
|
||||
startServer();
|
||||
startServer();
|
||||
|
||||
Reference in New Issue
Block a user