Compare commits
6 Commits
000a77ccf4
...
v1.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d14e97d7bd | ||
|
|
ef891f8e01 | ||
|
|
96ba5d034f | ||
|
|
2402b7cbc8 | ||
|
|
79b2fa5570 | ||
|
|
35fa172d36 |
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "app-ts",
|
"name": "app-ts",
|
||||||
"version": "1.3.8",
|
"version": "1.4.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "app-ts",
|
"name": "app-ts",
|
||||||
"version": "1.3.8",
|
"version": "1.4.1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "app-ts",
|
"name": "app-ts",
|
||||||
"version": "1.3.8",
|
"version": "1.4.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "dist/server.js",
|
"main": "dist/server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export default function LeaveRequests() {
|
|||||||
|
|
||||||
const fetchRequests = useCallback(async () => {
|
const fetchRequests = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await apiFetch(`${API_BASE}/leave-requests`);
|
const response = await apiFetch(`${API_BASE}/leave-requests?mine=1`);
|
||||||
if (response.status === 401) return;
|
if (response.status === 401) return;
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export default function TripsAdmin() {
|
|||||||
try {
|
try {
|
||||||
const [vRes, uRes, csRes] = await Promise.all([
|
const [vRes, uRes, csRes] = await Promise.all([
|
||||||
apiFetch(`${API_BASE}/vehicles`),
|
apiFetch(`${API_BASE}/vehicles`),
|
||||||
apiFetch(`${API_BASE}/users?limit=1000`),
|
apiFetch(`${API_BASE}/trips/users`),
|
||||||
apiFetch(`${API_BASE}/company-settings`),
|
apiFetch(`${API_BASE}/company-settings`),
|
||||||
]);
|
]);
|
||||||
const vJson = await vRes.json();
|
const vJson = await vRes.json();
|
||||||
@@ -136,14 +136,7 @@ export default function TripsAdmin() {
|
|||||||
if (vJson.success) setVehicles(vJson.data);
|
if (vJson.success) setVehicles(vJson.data);
|
||||||
if (csJson.success) setCompanyName(csJson.data.company_name || "");
|
if (csJson.success) setCompanyName(csJson.data.company_name || "");
|
||||||
if (uJson.success) {
|
if (uJson.success) {
|
||||||
setUsers(
|
setUsers(uJson.data);
|
||||||
uJson.data.map(
|
|
||||||
(u: { id: number; first_name: string; last_name: string }) => ({
|
|
||||||
id: u.id,
|
|
||||||
name: `${u.first_name} ${u.last_name}`,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// silently fail, filters will just be empty
|
// silently fail, filters will just be empty
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default async function leaveRequestsRoutes(
|
|||||||
const isAdmin = authData.permissions.includes("attendance.approve");
|
const isAdmin = authData.permissions.includes("attendance.approve");
|
||||||
|
|
||||||
const where: Record<string, unknown> = {};
|
const where: Record<string, unknown> = {};
|
||||||
if (!isAdmin) where.user_id = authData.userId;
|
if (!isAdmin || query.mine === "1") where.user_id = authData.userId;
|
||||||
else if (query.user_id) where.user_id = Number(query.user_id);
|
else if (query.user_id) where.user_id = Number(query.user_id);
|
||||||
if (query.status) where.status = String(query.status);
|
if (query.status) where.status = String(query.status);
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,45 @@ export default async function tripsRoutes(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// GET /api/admin/trips/users — users with trips.record permission
|
||||||
|
fastify.get(
|
||||||
|
"/users",
|
||||||
|
{ preHandler: requireAuth },
|
||||||
|
async (_request, reply) => {
|
||||||
|
const users = await prisma.users.findMany({
|
||||||
|
where: {
|
||||||
|
is_active: true,
|
||||||
|
roles: {
|
||||||
|
is: {
|
||||||
|
OR: [
|
||||||
|
{ name: "admin" },
|
||||||
|
{
|
||||||
|
role_permissions: {
|
||||||
|
some: { permissions: { name: "trips.record" } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
first_name: true,
|
||||||
|
last_name: true,
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
orderBy: { last_name: "asc" },
|
||||||
|
});
|
||||||
|
return success(
|
||||||
|
reply,
|
||||||
|
users.map((u) => ({
|
||||||
|
id: u.id,
|
||||||
|
name: `${u.first_name} ${u.last_name}`.trim() || u.username,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// GET /api/admin/trips/print — print data for trip report
|
// GET /api/admin/trips/print — print data for trip report
|
||||||
fastify.get(
|
fastify.get(
|
||||||
"/print",
|
"/print",
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ export const AttendanceBalancesSchema = z.object({
|
|||||||
|
|
||||||
export const AttendanceBulkSchema = z.object({
|
export const AttendanceBulkSchema = z.object({
|
||||||
month: z.string().regex(/^\d{4}-\d{2}$/, "Měsíc je povinný (formát YYYY-MM)"),
|
month: z.string().regex(/^\d{4}-\d{2}$/, "Měsíc je povinný (formát YYYY-MM)"),
|
||||||
user_ids: z.array(z.number()).min(1, "Vyberte alespoň jednoho zaměstnance"),
|
user_ids: z
|
||||||
|
.array(z.union([z.number(), z.string()]).transform((v) => Number(v)))
|
||||||
|
.min(1, "Vyberte alespoň jednoho zaměstnance"),
|
||||||
arrival_time: z.string().optional().default("08:00"),
|
arrival_time: z.string().optional().default("08:00"),
|
||||||
departure_time: z.string().optional().default("16:30"),
|
departure_time: z.string().optional().default("16:30"),
|
||||||
break_start_time: z.string().optional().default("12:00"),
|
break_start_time: z.string().optional().default("12:00"),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { attendance_leave_type, Prisma } from "@prisma/client";
|
import { attendance_leave_type, Prisma } from "@prisma/client";
|
||||||
import prisma from "../config/database";
|
import prisma from "../config/database";
|
||||||
import { getBusinessDaysInMonth } from "../utils/czech-holidays";
|
import { getBusinessDaysInMonth, isHoliday } from "../utils/czech-holidays";
|
||||||
import { localDateStr } from "../utils/date";
|
import { localDateStr } from "../utils/date";
|
||||||
import { getSystemSettings } from "./system-settings";
|
import { getSystemSettings } from "./system-settings";
|
||||||
|
|
||||||
@@ -1087,6 +1087,7 @@ export async function bulkCreateAttendance(data: BulkAttendanceData) {
|
|||||||
const dow = date.getDay();
|
const dow = date.getDay();
|
||||||
|
|
||||||
if (dow === 0 || dow === 6) continue;
|
if (dow === 0 || dow === 6) continue;
|
||||||
|
if (isHoliday(dateStr)) continue;
|
||||||
|
|
||||||
if (existingSet.has(`${userId}:${dateStr}`)) {
|
if (existingSet.has(`${userId}:${dateStr}`)) {
|
||||||
skipped++;
|
skipped++;
|
||||||
|
|||||||
Reference in New Issue
Block a user