diff --git a/README.md b/README.md index 54e6b1b..b5e8f35 100644 --- a/README.md +++ b/README.md @@ -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 \ No newline at end of file +**Yakıt Takip Uygulaması** - Modern Akaryakıt İstasyonu Yönetim Sistemi \ No newline at end of file diff --git a/docs/PROJECT_PROCESSES.md b/docs/PROJECT_PROCESSES.md index 60ff4d3..16ba9da 100644 --- a/docs/PROJECT_PROCESSES.md +++ b/docs/PROJECT_PROCESSES.md @@ -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* \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 9b88394..251f9b0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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ı diff --git a/src/app.html b/src/app.html index c883c41..d5d3b5e 100644 --- a/src/app.html +++ b/src/app.html @@ -4,7 +4,7 @@ - Yakıt Takip Modülü + Yakıt Takip Uygulaması %sveltekit.head% diff --git a/src/lib/components/GoodsManagersContent.svelte b/src/lib/components/GoodsManagersContent.svelte index c1e33a4..046af9e 100644 --- a/src/lib/components/GoodsManagersContent.svelte +++ b/src/lib/components/GoodsManagersContent.svelte @@ -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', diff --git a/src/lib/components/PersonnelContent.svelte b/src/lib/components/PersonnelContent.svelte index d940834..073e97b 100644 --- a/src/lib/components/PersonnelContent.svelte +++ b/src/lib/components/PersonnelContent.svelte @@ -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) { {person.tc_kimlik} -
-
- -
-
- İrtibat: - {person.phone} -
-
- +
+
+ +
+
+ İrtibat: + {person.phone} +
+
+
+
+ +
+
+ Görev Yeri: + Fuel Station +
+
+
-
- - -
-
- - -
+

+ {vehicle.unit_name || getUnitName(vehicle.unit_id, units)} +

-
- - -
+
+ + +
+
+ + +
-
+
+ + +
+
+ + +
- - {#each units as unit} - - {/each} - -
-
- - -
+

+ {vehicle.unit_name || getUnitName(vehicle.unit_id, units)} +

+
+ + +
+
+ + +
- {#each units as unit} @@ -437,10 +481,20 @@
- + {#if !formData.unit_id} + + {:else if filteredReceivingPersonnel.length === 0} + + {/if} + {#each filteredReceivingPersonnel as person} + {/each}
@@ -1042,4 +1096,4 @@ min-width: auto; } } - \ No newline at end of file + diff --git a/src/server.js b/src/server.js index 498868c..bc06c72 100644 --- a/src/server.js +++ b/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(); \ No newline at end of file +startServer();