Formlardaki filtrelemeler düzeltildi.
This commit is contained in:
@@ -2,17 +2,22 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
export let user = null;
|
export let user = null;
|
||||||
|
|
||||||
let vehicles = [];
|
let vehicles = [];
|
||||||
let units = [];
|
let units = [];
|
||||||
let loading = true;
|
let loading = true;
|
||||||
let error = '';
|
let error = '';
|
||||||
|
let unitWarning = '';
|
||||||
let showAddModal = false;
|
let showAddModal = false;
|
||||||
let showEditModal = false;
|
let showEditModal = false;
|
||||||
let selectedVehicle = null;
|
let selectedVehicle = null;
|
||||||
|
|
||||||
// Form değişkenleri
|
let isAdmin = false;
|
||||||
|
let isGoodsManager = false;
|
||||||
|
let managerUnitId = null;
|
||||||
|
let managerUnitName = '';
|
||||||
|
|
||||||
let formData = {
|
let formData = {
|
||||||
brand: '',
|
brand: '',
|
||||||
model: '',
|
model: '',
|
||||||
@@ -26,6 +31,37 @@ let formData = {
|
|||||||
kislik_mukannen: 0
|
kislik_mukannen: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$: {
|
||||||
|
isAdmin = user?.role === 'admin';
|
||||||
|
isGoodsManager = user?.role === 'goods_manager';
|
||||||
|
managerUnitId = isGoodsManager && user?.unit_id ? parseInt(user.unit_id) : null;
|
||||||
|
managerUnitName = isGoodsManager ? (user?.unit_name || getUnitName(user?.unit_id)) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if (isGoodsManager && !managerUnitId) {
|
||||||
|
unitWarning = 'Birlik bilginiz bulunamadı. Lütfen sistem yöneticisine başvurun.';
|
||||||
|
} else {
|
||||||
|
unitWarning = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: {
|
||||||
|
const managerUnitValue = managerUnitId ? managerUnitId.toString() : '';
|
||||||
|
if (
|
||||||
|
isGoodsManager &&
|
||||||
|
managerUnitId &&
|
||||||
|
formData.unit_id !== managerUnitValue &&
|
||||||
|
!showEditModal &&
|
||||||
|
(!showAddModal || (showAddModal && !formData.unit_id))
|
||||||
|
) {
|
||||||
|
formData = {
|
||||||
|
...formData,
|
||||||
|
unit_id: managerUnitValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await loadUnits();
|
await loadUnits();
|
||||||
await loadVehicles();
|
await loadVehicles();
|
||||||
@@ -37,6 +73,9 @@ async function loadUnits() {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
units = data.units || [];
|
units = data.units || [];
|
||||||
|
if (isGoodsManager && managerUnitId) {
|
||||||
|
managerUnitName = getUnitName(managerUnitId, units);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Load units error:', err);
|
console.error('Load units error:', err);
|
||||||
@@ -48,7 +87,15 @@ async function loadUnits() {
|
|||||||
const response = await fetch('/api/vehicles');
|
const response = await fetch('/api/vehicles');
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
vehicles = data.vehicles;
|
let fetchedVehicles = data.vehicles || [];
|
||||||
|
if (isGoodsManager) {
|
||||||
|
if (managerUnitId) {
|
||||||
|
fetchedVehicles = fetchedVehicles.filter(vehicle => vehicle.unit_id === managerUnitId);
|
||||||
|
} else {
|
||||||
|
fetchedVehicles = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vehicles = fetchedVehicles;
|
||||||
} else {
|
} else {
|
||||||
error = 'Araçlar yüklenemedi.';
|
error = 'Araçlar yüklenemedi.';
|
||||||
}
|
}
|
||||||
@@ -66,7 +113,7 @@ function resetForm() {
|
|||||||
model: '',
|
model: '',
|
||||||
year: new Date().getFullYear(),
|
year: new Date().getFullYear(),
|
||||||
plate: '',
|
plate: '',
|
||||||
unit_id: '',
|
unit_id: isGoodsManager && managerUnitId ? managerUnitId.toString() : '',
|
||||||
fuel_type: 'Benzin',
|
fuel_type: 'Benzin',
|
||||||
fuel_capacity: 50,
|
fuel_capacity: 50,
|
||||||
current_fuel: 0,
|
current_fuel: 0,
|
||||||
@@ -115,11 +162,21 @@ function validateMukannen(value) {
|
|||||||
|
|
||||||
function getUnitName(unitId, unitList = units) {
|
function getUnitName(unitId, unitList = units) {
|
||||||
const id = parseInt(unitId);
|
const id = parseInt(unitId);
|
||||||
return unitList.find((unit) => unit.id === id)?.name || 'Belirtilmemiş';
|
const unitName = unitList.find((unit) => unit.id === id)?.name;
|
||||||
|
if (unitName) return unitName;
|
||||||
|
if (isGoodsManager && managerUnitId === id) {
|
||||||
|
return managerUnitName || 'Belirtilmemiş';
|
||||||
|
}
|
||||||
|
return 'Belirtilmemiş';
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleAddVehicle() {
|
async function handleAddVehicle() {
|
||||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate || !formData.unit_id || !formData.fuel_type || !formData.fuel_capacity) {
|
if (isGoodsManager && !managerUnitId) {
|
||||||
|
error = 'Birlik bilginiz bulunamadı. Lütfen sistem yöneticisine başvurun.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.brand || !formData.model || !formData.year || !formData.plate || (!isGoodsManager && !formData.unit_id) || !formData.fuel_type || !formData.fuel_capacity) {
|
||||||
error = 'Tüm zorunlu alanları doldurun.';
|
error = 'Tüm zorunlu alanları doldurun.';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -132,7 +189,7 @@ function getUnitName(unitId, unitList = units) {
|
|||||||
try {
|
try {
|
||||||
const payload = {
|
const payload = {
|
||||||
...formData,
|
...formData,
|
||||||
unit_id: parseInt(formData.unit_id)
|
unit_id: isGoodsManager && managerUnitId ? managerUnitId : parseInt(formData.unit_id)
|
||||||
};
|
};
|
||||||
const response = await fetch('/api/vehicles', {
|
const response = await fetch('/api/vehicles', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -157,8 +214,13 @@ function getUnitName(unitId, unitList = units) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleUpdateVehicle() {
|
async function handleUpdateVehicle() {
|
||||||
if (!formData.brand || !formData.model || !formData.year || !formData.plate || !formData.unit_id || !formData.fuel_type || !formData.fuel_capacity) {
|
if (isGoodsManager && !managerUnitId) {
|
||||||
|
error = 'Birlik bilginiz bulunamadı. Lütfen sistem yöneticisine başvurun.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.brand || !formData.model || !formData.year || !formData.plate || (!isGoodsManager && !formData.unit_id) || !formData.fuel_type || !formData.fuel_capacity) {
|
||||||
error = 'Tüm zorunlu alanları doldurun.';
|
error = 'Tüm zorunlu alanları doldurun.';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -172,7 +234,7 @@ function getUnitName(unitId, unitList = units) {
|
|||||||
const payload = {
|
const payload = {
|
||||||
id: selectedVehicle.id,
|
id: selectedVehicle.id,
|
||||||
...formData,
|
...formData,
|
||||||
unit_id: parseInt(formData.unit_id)
|
unit_id: isGoodsManager && managerUnitId ? managerUnitId : parseInt(formData.unit_id)
|
||||||
};
|
};
|
||||||
const response = await fetch('/api/vehicles', {
|
const response = await fetch('/api/vehicles', {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
@@ -233,7 +295,7 @@ function getUnitName(unitId, unitList = units) {
|
|||||||
<span class="count">{vehicles.length}</span>
|
<span class="count">{vehicles.length}</span>
|
||||||
<span>Araç</span>
|
<span>Araç</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary" on:click={openAddModal}>
|
<button class="btn btn-primary" on:click={openAddModal} disabled={isGoodsManager && !managerUnitId}>
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
<line x1="12" y1="5" x2="12" y2="19"/>
|
<line x1="12" y1="5" x2="12" y2="19"/>
|
||||||
<line x1="5" y1="12" x2="19" y2="12"/>
|
<line x1="5" y1="12" x2="19" y2="12"/>
|
||||||
@@ -247,6 +309,11 @@ function getUnitName(unitId, unitList = units) {
|
|||||||
{error}
|
{error}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if unitWarning}
|
||||||
|
<div class="error-message">
|
||||||
|
{unitWarning}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="loading-container">
|
<div class="loading-container">
|
||||||
@@ -364,20 +431,32 @@ function getUnitName(unitId, unitList = units) {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
{#if isAdmin}
|
||||||
<label for="unit_id">Birlik</label>
|
<div class="form-group">
|
||||||
<select
|
<label for="unit_id">Birlik</label>
|
||||||
id="unit_id"
|
<select
|
||||||
class="form-input"
|
id="unit_id"
|
||||||
bind:value={formData.unit_id}
|
class="form-input"
|
||||||
required
|
bind:value={formData.unit_id}
|
||||||
>
|
required
|
||||||
<option value="">Birlik Seçin</option>
|
>
|
||||||
{#each units as unit}
|
<option value="">Birlik Seçin</option>
|
||||||
<option value={unit.id}>{unit.name}</option>
|
{#each units as unit}
|
||||||
{/each}
|
<option value={unit.id}>{unit.name}</option>
|
||||||
</select>
|
{/each}
|
||||||
</div>
|
</select>
|
||||||
|
</div>
|
||||||
|
{:else if isGoodsManager}
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Birlik</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-input"
|
||||||
|
value={managerUnitName || 'Birlik bilgisi bulunamadı'}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="fuel_type">Yakıt Tipi</label>
|
<label for="fuel_type">Yakıt Tipi</label>
|
||||||
<select
|
<select
|
||||||
@@ -509,20 +588,32 @@ function getUnitName(unitId, unitList = units) {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
{#if isAdmin}
|
||||||
<label for="edit-unit_id">Birlik</label>
|
<div class="form-group">
|
||||||
<select
|
<label for="edit-unit_id">Birlik</label>
|
||||||
id="edit-unit_id"
|
<select
|
||||||
class="form-input"
|
id="edit-unit_id"
|
||||||
bind:value={formData.unit_id}
|
class="form-input"
|
||||||
required
|
bind:value={formData.unit_id}
|
||||||
>
|
required
|
||||||
<option value="">Birlik Seçin</option>
|
>
|
||||||
{#each units as unit}
|
<option value="">Birlik Seçin</option>
|
||||||
<option value={unit.id}>{unit.name}</option>
|
{#each units as unit}
|
||||||
{/each}
|
<option value={unit.id}>{unit.name}</option>
|
||||||
</select>
|
{/each}
|
||||||
</div>
|
</select>
|
||||||
|
</div>
|
||||||
|
{:else if isGoodsManager}
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Birlik</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-input"
|
||||||
|
value={managerUnitName || 'Birlik bilgisi bulunamadı'}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="edit-fuel_type">Yakıt Tipi</label>
|
<label for="edit-fuel_type">Yakıt Tipi</label>
|
||||||
<select
|
<select
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
let showMobileMenu = false;
|
let showMobileMenu = false;
|
||||||
let showFuelForm = false;
|
let showFuelForm = false;
|
||||||
let showGoodsManager = false;
|
let showGoodsManager = false;
|
||||||
|
let showGoodsManagerVehicles = false;
|
||||||
let showVehicles = false;
|
let showVehicles = false;
|
||||||
let showUnits = false;
|
let showUnits = false;
|
||||||
let showPersonnel = false;
|
let showPersonnel = false;
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
showGoodsManagers = false;
|
showGoodsManagers = false;
|
||||||
showFuelForm = false;
|
showFuelForm = false;
|
||||||
showGoodsManager = false;
|
showGoodsManager = false;
|
||||||
|
showGoodsManagerVehicles = false;
|
||||||
showDevriçark = false;
|
showDevriçark = false;
|
||||||
showMonthlyReport = false;
|
showMonthlyReport = false;
|
||||||
}
|
}
|
||||||
@@ -106,7 +108,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eğer goods_manager ise socket bağlantısı kur (GoodsManagerContent component'i kendi socket'ini kullanacak)
|
|
||||||
if (user.role === "goods_manager") {
|
if (user.role === "goods_manager") {
|
||||||
console.log("Dashboard - goods_manager logged in, user:", user);
|
console.log("Dashboard - goods_manager logged in, user:", user);
|
||||||
}
|
}
|
||||||
@@ -407,6 +408,7 @@
|
|||||||
|
|
||||||
if (page === "" && user?.role === "goods_manager") {
|
if (page === "" && user?.role === "goods_manager") {
|
||||||
showGoodsManager = false;
|
showGoodsManager = false;
|
||||||
|
showGoodsManagerVehicles = false;
|
||||||
showDevriçark = false;
|
showDevriçark = false;
|
||||||
showMonthlyReport = false;
|
showMonthlyReport = false;
|
||||||
showMobileMenu = false;
|
showMobileMenu = false;
|
||||||
@@ -416,6 +418,7 @@
|
|||||||
if (page === "goods-manager" && user?.role === "goods_manager") {
|
if (page === "goods-manager" && user?.role === "goods_manager") {
|
||||||
console.log("🎯 Navigating to goods-manager, user:", user);
|
console.log("🎯 Navigating to goods-manager, user:", user);
|
||||||
showGoodsManager = true;
|
showGoodsManager = true;
|
||||||
|
showGoodsManagerVehicles = false;
|
||||||
showDevriçark = false;
|
showDevriçark = false;
|
||||||
showMonthlyReport = false;
|
showMonthlyReport = false;
|
||||||
showMobileMenu = false;
|
showMobileMenu = false;
|
||||||
@@ -425,6 +428,7 @@
|
|||||||
if (page === "devriçark" && user?.role === "goods_manager") {
|
if (page === "devriçark" && user?.role === "goods_manager") {
|
||||||
console.log("🎯 Navigating to devriçark, user:", user);
|
console.log("🎯 Navigating to devriçark, user:", user);
|
||||||
showGoodsManager = false;
|
showGoodsManager = false;
|
||||||
|
showGoodsManagerVehicles = false;
|
||||||
showDevriçark = true;
|
showDevriçark = true;
|
||||||
showMonthlyReport = false;
|
showMonthlyReport = false;
|
||||||
showMobileMenu = false;
|
showMobileMenu = false;
|
||||||
@@ -434,12 +438,22 @@
|
|||||||
if (page === "aylik-yakit-dokumu" && user?.role === "goods_manager") {
|
if (page === "aylik-yakit-dokumu" && user?.role === "goods_manager") {
|
||||||
console.log("🎯 Navigating to aylik-yakit-dokumu, user:", user);
|
console.log("🎯 Navigating to aylik-yakit-dokumu, user:", user);
|
||||||
showGoodsManager = false;
|
showGoodsManager = false;
|
||||||
|
showGoodsManagerVehicles = false;
|
||||||
showDevriçark = false;
|
showDevriçark = false;
|
||||||
showMonthlyReport = true;
|
showMonthlyReport = true;
|
||||||
showMobileMenu = false;
|
showMobileMenu = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (page === "goods-manager-vehicles" && user?.role === "goods_manager") {
|
||||||
|
showGoodsManager = false;
|
||||||
|
showDevriçark = false;
|
||||||
|
showMonthlyReport = false;
|
||||||
|
showGoodsManagerVehicles = true;
|
||||||
|
showMobileMenu = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (page === "distribution-document" && user?.role === "fuel_manager") {
|
if (page === "distribution-document" && user?.role === "fuel_manager") {
|
||||||
// Dağıtım belgesi sayfasına yönlendir (gelecekte oluşturulacak)
|
// Dağıtım belgesi sayfasına yönlendir (gelecekte oluşturulacak)
|
||||||
showMobileMenu = false;
|
showMobileMenu = false;
|
||||||
@@ -548,7 +562,10 @@
|
|||||||
!showPersonnel &&
|
!showPersonnel &&
|
||||||
!showGoodsManagers
|
!showGoodsManagers
|
||||||
: user.role === "goods_manager"
|
: user.role === "goods_manager"
|
||||||
? !showGoodsManager && !showDevriçark && !showMonthlyReport
|
? !showGoodsManager &&
|
||||||
|
!showGoodsManagerVehicles &&
|
||||||
|
!showDevriçark &&
|
||||||
|
!showMonthlyReport
|
||||||
: user.role !== "fuel_manager"
|
: user.role !== "fuel_manager"
|
||||||
? !showFuelForm
|
? !showFuelForm
|
||||||
: true}
|
: true}
|
||||||
@@ -725,6 +742,30 @@
|
|||||||
Atanan Fişler
|
Atanan Fişler
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<button
|
||||||
|
class="nav-btn"
|
||||||
|
on:click={() => navigateTo("goods-manager-vehicles")}
|
||||||
|
class:active={showGoodsManagerVehicles}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
>
|
||||||
|
<path d="M5 16l-1.5 3" />
|
||||||
|
<path d="M19 16l1.5 3" />
|
||||||
|
<path d="M7 16h10" />
|
||||||
|
<path d="M6 16v-6a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v6" />
|
||||||
|
<circle cx="7.5" cy="19.5" r="1.5" />
|
||||||
|
<circle cx="16.5" cy="19.5" r="1.5" />
|
||||||
|
</svg>
|
||||||
|
Araç Yönetimi
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<button
|
<button
|
||||||
class="nav-btn"
|
class="nav-btn"
|
||||||
@@ -921,6 +962,8 @@
|
|||||||
{:else if user.role === "goods_manager" && showGoodsManager}
|
{:else if user.role === "goods_manager" && showGoodsManager}
|
||||||
<!-- Goods Manager Content -->
|
<!-- Goods Manager Content -->
|
||||||
<GoodsManagerContent {user} />
|
<GoodsManagerContent {user} />
|
||||||
|
{:else if user.role === "goods_manager" && showGoodsManagerVehicles}
|
||||||
|
<VehiclesContent {user} />
|
||||||
{:else if user.role === "goods_manager" && showMonthlyReport}
|
{:else if user.role === "goods_manager" && showMonthlyReport}
|
||||||
<!-- Monthly Fuel Report Content -->
|
<!-- Monthly Fuel Report Content -->
|
||||||
<MonthlyFuelReportContent {user} />
|
<MonthlyFuelReportContent {user} />
|
||||||
|
|||||||
244
src/server.js
244
src/server.js
@@ -12,7 +12,8 @@ import {
|
|||||||
addGoodsManager,
|
addGoodsManager,
|
||||||
updateGoodsManager,
|
updateGoodsManager,
|
||||||
deleteGoodsManager,
|
deleteGoodsManager,
|
||||||
findGoodsManagerById
|
findGoodsManagerById,
|
||||||
|
findGoodsManagerByUsername
|
||||||
} from './lib/data/goodsManagers.js';
|
} from './lib/data/goodsManagers.js';
|
||||||
|
|
||||||
// Units veritabanı
|
// Units veritabanı
|
||||||
@@ -292,12 +293,37 @@ async function initializeDatabase() {
|
|||||||
password TEXT NOT NULL,
|
password TEXT NOT NULL,
|
||||||
role TEXT NOT NULL,
|
role TEXT NOT NULL,
|
||||||
full_name TEXT,
|
full_name TEXT,
|
||||||
|
unit_id INTEGER,
|
||||||
|
unit_name TEXT,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
is_active BOOLEAN DEFAULT 1
|
is_active BOOLEAN DEFAULT 1
|
||||||
)`, (err) => {
|
)`, (err) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ensure optional columns exist (for older databases)
|
||||||
|
db.all('PRAGMA table_info(users)', (pragmaErr, columns) => {
|
||||||
|
if (pragmaErr) {
|
||||||
|
console.error('⚠️ Unable to inspect users table columns:', pragmaErr);
|
||||||
|
} else {
|
||||||
|
const colNames = columns.map(col => col.name);
|
||||||
|
const ensureColumn = (name, definition) => {
|
||||||
|
if (!colNames.includes(name)) {
|
||||||
|
db.run(`ALTER TABLE users ADD COLUMN ${definition}`, (alterErr) => {
|
||||||
|
if (alterErr) {
|
||||||
|
console.warn(`⚠️ Could not add column ${name}:`, alterErr.message);
|
||||||
|
} else {
|
||||||
|
console.log(`ℹ️ Added column ${name} to users table.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ensureColumn('unit_id', 'unit_id INTEGER');
|
||||||
|
ensureColumn('unit_name', 'unit_name TEXT');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Yakıt fişleri tablosu
|
// Yakıt fişleri tablosu
|
||||||
db.run(`CREATE TABLE IF NOT EXISTS fuel_slips (
|
db.run(`CREATE TABLE IF NOT EXISTS fuel_slips (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@@ -328,24 +354,28 @@ async function initializeDatabase() {
|
|||||||
// Tablolar oluşturulduktan sonra kullanıcıları ekle
|
// Tablolar oluşturulduktan sonra kullanıcıları ekle
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
// Örnek kullanıcıları ekle
|
// Örnek kullanıcıları ekle
|
||||||
const users = [
|
const users = [
|
||||||
{ username: 'admin', password: 'admin123', role: 'admin', full_name: 'Sistem Yöneticisi' },
|
{ username: 'admin', password: 'admin123', role: 'admin', full_name: 'Sistem Yöneticisi' },
|
||||||
{ username: 'fuel', password: 'fuel123', role: 'fuel_manager', full_name: 'Yakıt Sorumlusu' },
|
{ username: 'fuel', password: 'fuel123', role: 'fuel_manager', full_name: 'Yakıt Sorumlusu' },
|
||||||
{ username: 'goods', password: 'goods123', role: 'goods_manager', full_name: 'Mal Sorumlusu' },
|
{ username: 'goods', password: 'goods123', role: 'goods_manager', full_name: 'Ali Veli', unit_id: 1, unit_name: '1. Motorlu Piyade Tugayı' },
|
||||||
{ username: 'ibrahim_kara', password: 'kara123', role: 'goods_manager', full_name: 'İbrahim Kara' }
|
{ username: 'ibrahim_kara', password: 'kara123', role: 'goods_manager', full_name: 'İbrahim Kara', unit_id: 2, unit_name: '2. Zırhlı Tabur' },
|
||||||
];
|
{ username: 'osmankocak', password: 'osman123', role: 'goods_manager', full_name: 'Osman Koçak', unit_id: 3, unit_name: '3. Komutanlık' }
|
||||||
|
];
|
||||||
|
|
||||||
// Her kullanıcıyı kontrol et ve yoksa ekle
|
// Her kullanıcıyı kontrol et ve yoksa ekle
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
const hashedPassword = await bcrypt.hash(user.password, 10);
|
const hashedPassword = await bcrypt.hash(user.password, 10);
|
||||||
|
|
||||||
db.get('SELECT id FROM users WHERE username = ?', [user.username], (err, row) => {
|
db.get('SELECT id, unit_id, unit_name FROM users WHERE username = ?', [user.username], (err, row) => {
|
||||||
if (!row) {
|
if (!row) {
|
||||||
db.run('INSERT INTO users (username, password, role, full_name) VALUES (?, ?, ?, ?)',
|
db.run('INSERT INTO users (username, password, role, full_name, unit_id, unit_name) VALUES (?, ?, ?, ?, ?, ?)',
|
||||||
[user.username, hashedPassword, user.role, user.full_name]);
|
[user.username, hashedPassword, user.role, user.full_name, user.unit_id || null, user.unit_name || null]);
|
||||||
}
|
} else if ((user.unit_id && !row.unit_id) || (user.unit_name && !row.unit_name)) {
|
||||||
});
|
db.run('UPDATE users SET unit_id = COALESCE(unit_id, ?), unit_name = COALESCE(unit_name, ?) WHERE username = ?',
|
||||||
}
|
[user.unit_id || null, user.unit_name || null, user.username]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
resolve();
|
resolve();
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
@@ -382,23 +412,35 @@ app.post('/api/login', async (req, res) => {
|
|||||||
id: user.id,
|
id: user.id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
full_name: user.full_name
|
full_name: user.full_name,
|
||||||
|
unit_id: user.unit_id ? parseInt(user.unit_id) : null,
|
||||||
|
unit_name: user.unit_name || null
|
||||||
};
|
};
|
||||||
|
|
||||||
// Eğer goods_manager ise, goods_managers API'den gerçek ID'yi al
|
// Eğer goods_manager ise, goodsManagers verisinden profil bilgilerini al
|
||||||
if (user.role === 'goods_manager') {
|
if (user.role === 'goods_manager') {
|
||||||
try {
|
const goodsManager = findGoodsManagerByUsername(user.username);
|
||||||
const goodsManagersRes = await fetch('http://localhost:3000/api/goods-managers');
|
if (goodsManager) {
|
||||||
if (goodsManagersRes.ok) {
|
sessionUser.goods_manager_profile_id = goodsManager.id;
|
||||||
const goodsData = await goodsManagersRes.json();
|
sessionUser.id = goodsManager.id;
|
||||||
const goodsManager = goodsData.goodsManagers?.find(gm => gm.username === user.username);
|
if (!sessionUser.unit_id || !sessionUser.unit_name) {
|
||||||
if (goodsManager) {
|
sessionUser.unit_id = goodsManager.unit_id;
|
||||||
sessionUser.id = goodsManager.id; // goods_manager ID'sini kullan
|
sessionUser.unit_name = goodsManager.unit_name;
|
||||||
console.log(`✅ Goods manager logged in: ${user.full_name} (ID: ${goodsManager.id})`);
|
sessionUser.rank = goodsManager.rank;
|
||||||
}
|
db.run('UPDATE users SET unit_id = ?, unit_name = ? WHERE id = ?', [
|
||||||
|
goodsManager.unit_id,
|
||||||
|
goodsManager.unit_name,
|
||||||
|
user.id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (!sessionUser.rank) {
|
||||||
|
sessionUser.rank = goodsManager.rank;
|
||||||
|
}
|
||||||
|
console.log(`✅ Goods manager logged in: ${goodsManager.full_name} (ID: ${goodsManager.id})`);
|
||||||
|
} else {
|
||||||
|
if (!sessionUser.unit_id || !sessionUser.unit_name) {
|
||||||
|
console.warn(`⚠️ Goods manager profile not found for username: ${user.username}`);
|
||||||
}
|
}
|
||||||
} catch (fetchError) {
|
|
||||||
console.warn('⚠️ Could not fetch goods manager ID:', fetchError);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,11 +578,21 @@ app.post('/api/units', async (req, res) => {
|
|||||||
|
|
||||||
// Mal sorumlusu kullanıcı olarak ekle
|
// Mal sorumlusu kullanıcı olarak ekle
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
db.run('INSERT INTO users (username, password, role, full_name) VALUES (?, ?, ?, ?)',
|
db.run(
|
||||||
[username, hashedPassword, 'goods_manager', full_name], (err) => {
|
'INSERT INTO users (username, password, role, full_name, unit_id, unit_name) VALUES (?, ?, ?, ?, ?, ?)',
|
||||||
|
[
|
||||||
|
username.trim(),
|
||||||
|
hashedPassword,
|
||||||
|
'goods_manager',
|
||||||
|
full_name.trim(),
|
||||||
|
newUnit.id,
|
||||||
|
newUnit.name
|
||||||
|
],
|
||||||
|
(err) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
else resolve();
|
else resolve();
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`✅ Mal sorumlusu kullanıcı oluşturuldu: ${username}`);
|
console.log(`✅ Mal sorumlusu kullanıcı oluşturuldu: ${username}`);
|
||||||
@@ -597,6 +649,12 @@ app.put('/api/units', async (req, res) => {
|
|||||||
return res.status(404).json({ message: 'Birlik bulunamadı.' });
|
return res.status(404).json({ message: 'Birlik bulunamadı.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mevcut komutan bilgisini sakla (DB senkronu için)
|
||||||
|
const previousUnitState = {
|
||||||
|
...units[unitIndex],
|
||||||
|
commander: { ...units[unitIndex].commander }
|
||||||
|
};
|
||||||
|
|
||||||
// Birlik güncelle
|
// Birlik güncelle
|
||||||
const updatedCommander = {
|
const updatedCommander = {
|
||||||
full_name: full_name.trim(),
|
full_name: full_name.trim(),
|
||||||
@@ -607,6 +665,7 @@ app.put('/api/units', async (req, res) => {
|
|||||||
username: username.trim(),
|
username: username.trim(),
|
||||||
password: password.trim()
|
password: password.trim()
|
||||||
};
|
};
|
||||||
|
const previousCommanderUsername = previousUnitState?.commander?.username || updatedCommander.username;
|
||||||
|
|
||||||
units[unitIndex] = {
|
units[unitIndex] = {
|
||||||
...units[unitIndex],
|
...units[unitIndex],
|
||||||
@@ -617,31 +676,41 @@ app.put('/api/units', async (req, res) => {
|
|||||||
commander: updatedCommander
|
commander: updatedCommander
|
||||||
};
|
};
|
||||||
|
|
||||||
// Eğer kullanıcı adı veya şifre değişmişse, kullanıcıyı güncelle
|
// Mal sorumlusu kullanıcı kaydını güncelle
|
||||||
const oldCommander = units[unitIndex].commander;
|
try {
|
||||||
if (oldCommander.username !== username || password !== oldCommander.password) {
|
const hashedPassword = await bcrypt.hash(password, 10);
|
||||||
try {
|
|
||||||
const hashedPassword = await bcrypt.hash(password, 10);
|
|
||||||
|
|
||||||
// Kullanıcıyı güncelle
|
await new Promise((resolve, reject) => {
|
||||||
await new Promise((resolve, reject) => {
|
db.run(
|
||||||
db.run('UPDATE users SET username = ?, password = ?, full_name = ? WHERE username = ?',
|
`UPDATE users
|
||||||
[username, hashedPassword, full_name, oldCommander.username], (err) => {
|
SET username = ?, password = ?, full_name = ?, unit_id = ?, unit_name = ?
|
||||||
if (err) reject(err);
|
WHERE username = ?`,
|
||||||
else resolve();
|
[
|
||||||
});
|
updatedCommander.username,
|
||||||
});
|
hashedPassword,
|
||||||
|
updatedCommander.full_name,
|
||||||
|
units[unitIndex].id,
|
||||||
|
units[unitIndex].name,
|
||||||
|
previousCommanderUsername
|
||||||
|
],
|
||||||
|
function (err) {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
if (this.changes === 0) {
|
||||||
|
return reject(new Error('Mal sorumlusu kullanıcı kaydı bulunamadı.'));
|
||||||
|
}
|
||||||
|
return resolve();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
console.log(`✅ Mal sorumlusu kullanıcı güncellendi: ${username}`);
|
console.log(`✅ Mal sorumlusu kullanıcı güncellendi: ${updatedCommander.username}`);
|
||||||
} catch (userError) {
|
} catch (userError) {
|
||||||
console.error('❌ Mal sorumlusu kullanıcı güncelleme hatası:', userError);
|
console.error('❌ Mal sorumlusu kullanıcı güncelleme hatası:', userError);
|
||||||
// Kullanıcı güncellenemezse, birlik güncellemesi geri alınsın
|
// Kullanıcı güncellenemezse, birlik güncellemesi geri alınsın
|
||||||
units[unitIndex] = {
|
units[unitIndex] = previousUnitState;
|
||||||
...units[unitIndex],
|
return res.status(500).json({ message: 'Mal sorumlusu kullanıcı güncellenemedi.' });
|
||||||
commander: oldCommander
|
|
||||||
};
|
|
||||||
return res.status(500).json({ message: 'Mal sorumlusu kullanıcı güncellenemedi.' });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
@@ -1431,10 +1500,29 @@ app.delete('/api/fuel-slips', async (req, res) => {
|
|||||||
|
|
||||||
// Vehicles API endpoint'leri
|
// Vehicles API endpoint'leri
|
||||||
|
|
||||||
|
// Yardımcı: goods manager birlik bilgisi al
|
||||||
|
function getGoodsManagerUnit(req) {
|
||||||
|
const sessionUser = req.session?.user;
|
||||||
|
if (!sessionUser || sessionUser.role !== 'goods_manager') {
|
||||||
|
return { isGoodsManager: false, unitId: null };
|
||||||
|
}
|
||||||
|
const unitId = sessionUser.unit_id ? parseInt(sessionUser.unit_id) : null;
|
||||||
|
return { isGoodsManager: true, unitId };
|
||||||
|
}
|
||||||
|
|
||||||
// GET - Tüm araçları listele
|
// GET - Tüm araçları listele
|
||||||
app.get('/api/vehicles', (req, res) => {
|
app.get('/api/vehicles', (req, res) => {
|
||||||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
const { isGoodsManager, unitId } = getGoodsManagerUnit(req);
|
||||||
res.json({ vehicles });
|
|
||||||
|
if (isGoodsManager && !unitId) {
|
||||||
|
return res.status(400).json({ message: 'Birlik bilginiz tanımlı değil. Lütfen sistem yöneticisi ile iletişime geçin.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const filteredVehicles = isGoodsManager
|
||||||
|
? vehicles.filter(vehicle => vehicle.unit_id === unitId)
|
||||||
|
: vehicles;
|
||||||
|
|
||||||
|
res.json({ vehicles: filteredVehicles });
|
||||||
});
|
});
|
||||||
|
|
||||||
// POST - Yeni araç ekle
|
// POST - Yeni araç ekle
|
||||||
@@ -1442,6 +1530,7 @@ app.post('/api/vehicles', (req, res) => {
|
|||||||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const { isGoodsManager, unitId: managerUnitId } = getGoodsManagerUnit(req);
|
||||||
const {
|
const {
|
||||||
brand,
|
brand,
|
||||||
model,
|
model,
|
||||||
@@ -1458,12 +1547,18 @@ app.post('/api/vehicles', (req, res) => {
|
|||||||
driver_name
|
driver_name
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
|
const resolvedUnitId = isGoodsManager ? managerUnitId : parseInt(unit_id);
|
||||||
|
|
||||||
// Validasyon
|
// Validasyon
|
||||||
if (!brand || !model || !year || !plate || !unit_id || !fuel_type || !fuel_capacity) {
|
if (!brand || !model || !year || !plate || (!resolvedUnitId && !isGoodsManager) || !fuel_type || !fuel_capacity) {
|
||||||
return res.status(400).json({ message: 'Tüm zorunlu alanları doldurun.' });
|
return res.status(400).json({ message: 'Tüm zorunlu alanları doldurun.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetUnit = units.find(u => u.id === parseInt(unit_id));
|
if (isGoodsManager && !managerUnitId) {
|
||||||
|
return res.status(400).json({ message: 'Birlik bilginiz tanımlı değil. Lütfen sistem yöneticisi ile iletişime geçin.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetUnit = units.find(u => u.id === resolvedUnitId);
|
||||||
if (!targetUnit) {
|
if (!targetUnit) {
|
||||||
return res.status(400).json({ message: 'Geçerli bir birlik seçin.' });
|
return res.status(400).json({ message: 'Geçerli bir birlik seçin.' });
|
||||||
}
|
}
|
||||||
@@ -1492,7 +1587,7 @@ app.post('/api/vehicles', (req, res) => {
|
|||||||
model: model.trim(),
|
model: model.trim(),
|
||||||
year: parseInt(year),
|
year: parseInt(year),
|
||||||
plate: plate.trim().toUpperCase(),
|
plate: plate.trim().toUpperCase(),
|
||||||
unit_id: parseInt(unit_id),
|
unit_id: resolvedUnitId,
|
||||||
fuel_type: fuel_type.trim(),
|
fuel_type: fuel_type.trim(),
|
||||||
fuel_capacity: parseInt(fuel_capacity),
|
fuel_capacity: parseInt(fuel_capacity),
|
||||||
current_fuel: parseInt(current_fuel) || 0,
|
current_fuel: parseInt(current_fuel) || 0,
|
||||||
@@ -1522,6 +1617,7 @@ app.put('/api/vehicles', (req, res) => {
|
|||||||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const { isGoodsManager, unitId: managerUnitId } = getGoodsManagerUnit(req);
|
||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
brand,
|
brand,
|
||||||
@@ -1539,12 +1635,18 @@ app.put('/api/vehicles', (req, res) => {
|
|||||||
driver_name
|
driver_name
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
|
const resolvedUnitId = isGoodsManager ? managerUnitId : parseInt(unit_id);
|
||||||
|
|
||||||
// Validasyon
|
// Validasyon
|
||||||
if (!id || !brand || !model || !year || !plate || !unit_id || !fuel_type || !fuel_capacity) {
|
if (!id || !brand || !model || !year || !plate || (!resolvedUnitId && !isGoodsManager) || !fuel_type || !fuel_capacity) {
|
||||||
return res.status(400).json({ message: 'Tüm zorunlu alanları doldurun.' });
|
return res.status(400).json({ message: 'Tüm zorunlu alanları doldurun.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetUnit = units.find(u => u.id === parseInt(unit_id));
|
if (isGoodsManager && !managerUnitId) {
|
||||||
|
return res.status(400).json({ message: 'Birlik bilginiz tanımlı değil. Lütfen sistem yöneticisine başvurun.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetUnit = units.find(u => u.id === resolvedUnitId);
|
||||||
if (!targetUnit) {
|
if (!targetUnit) {
|
||||||
return res.status(400).json({ message: 'Geçerli bir birlik seçin.' });
|
return res.status(400).json({ message: 'Geçerli bir birlik seçin.' });
|
||||||
}
|
}
|
||||||
@@ -1563,6 +1665,10 @@ app.put('/api/vehicles', (req, res) => {
|
|||||||
return res.status(404).json({ message: 'Araç bulunamadı.' });
|
return res.status(404).json({ message: 'Araç bulunamadı.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isGoodsManager && vehicles[vehicleIndex].unit_id !== managerUnitId) {
|
||||||
|
return res.status(403).json({ message: 'Bu aracı güncelleme yetkiniz yok.' });
|
||||||
|
}
|
||||||
|
|
||||||
// Plaka tekrar kontrolü (diğer araçlar için)
|
// Plaka tekrar kontrolü (diğer araçlar için)
|
||||||
const existingVehicle = vehicles.find(v =>
|
const existingVehicle = vehicles.find(v =>
|
||||||
v.id !== parseInt(id) && v.plate.toLowerCase() === plate.toLowerCase()
|
v.id !== parseInt(id) && v.plate.toLowerCase() === plate.toLowerCase()
|
||||||
@@ -1579,7 +1685,7 @@ app.put('/api/vehicles', (req, res) => {
|
|||||||
model: model.trim(),
|
model: model.trim(),
|
||||||
year: parseInt(year),
|
year: parseInt(year),
|
||||||
plate: plate.trim().toUpperCase(),
|
plate: plate.trim().toUpperCase(),
|
||||||
unit_id: parseInt(unit_id),
|
unit_id: resolvedUnitId,
|
||||||
fuel_type: fuel_type.trim(),
|
fuel_type: fuel_type.trim(),
|
||||||
fuel_capacity: parseInt(fuel_capacity),
|
fuel_capacity: parseInt(fuel_capacity),
|
||||||
current_fuel: parseInt(current_fuel) || 0,
|
current_fuel: parseInt(current_fuel) || 0,
|
||||||
@@ -1612,6 +1718,7 @@ app.delete('/api/vehicles', (req, res) => {
|
|||||||
// Yetki kontrolü (temporary - will be implemented with proper session)
|
// Yetki kontrolü (temporary - will be implemented with proper session)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const { isGoodsManager, unitId: managerUnitId } = getGoodsManagerUnit(req);
|
||||||
const { id } = req.body;
|
const { id } = req.body;
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
@@ -1624,6 +1731,15 @@ app.delete('/api/vehicles', (req, res) => {
|
|||||||
return res.status(404).json({ message: 'Araç bulunamadı.' });
|
return res.status(404).json({ message: 'Araç bulunamadı.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isGoodsManager) {
|
||||||
|
if (!managerUnitId) {
|
||||||
|
return res.status(400).json({ message: 'Birlik bilginiz tanımlı değil. Lütfen sistem yöneticisine başvurun.' });
|
||||||
|
}
|
||||||
|
if (vehicles[vehicleIndex].unit_id !== managerUnitId) {
|
||||||
|
return res.status(403).json({ message: 'Bu aracı silme yetkiniz yok.' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Araç sil
|
// Araç sil
|
||||||
const deletedVehicle = vehicles.splice(vehicleIndex, 1)[0];
|
const deletedVehicle = vehicles.splice(vehicleIndex, 1)[0];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user