feat: fix backend SQL columns, add dark/light theme, fix legacy CSS
- Fix 7 backend controllers: rename columns to match actual DB schema (name_room→room_number, id_room→id, bed_type→room_type, id_employee→id, status_employee→status) - Fix 10 frontend files with matching property renames - Add ThemeContext with dark/light toggle (localStorage persisted) - Redesign theme.css with [data-theme] attribute selectors - Add Google Fonts (Syne, DM Sans, JetBrains Mono) - Redesign sidebar, topbar, and login page CSS - Migrate ~44 legacy CSS files from hardcoded colors to CSS variables - Remove Dashboards/Tableros section from menu - Clean up commented-out CSS blocks across codebase Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
130
backend/hotel_hacienda/package-lock.json
generated
130
backend/hotel_hacienda/package-lock.json
generated
@@ -10,11 +10,14 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.13.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"csv-parser": "^3.2.0",
|
||||
"dotenv": "^17.2.2",
|
||||
"express": "^5.1.0",
|
||||
"express-validator": "^7.2.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"nodemailer": "^7.0.10",
|
||||
"pg": "^8.16.3",
|
||||
"stripe": "^20.1.2",
|
||||
@@ -84,6 +87,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bcryptjs": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
|
||||
"integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
@@ -141,6 +150,12 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
@@ -275,6 +290,25 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
|
||||
"integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cookie": "0.7.2",
|
||||
"cookie-signature": "1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser/node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
||||
@@ -382,6 +416,15 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
@@ -872,12 +915,97 @@
|
||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jsonwebtoken": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz",
|
||||
"integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jws": "^4.0.1",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jwa": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
|
||||
"integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "^1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/jws": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^2.0.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
@@ -1070,7 +1198,6 @@
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
|
||||
"integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"pg-connection-string": "^2.9.1",
|
||||
"pg-pool": "^3.10.1",
|
||||
@@ -1331,7 +1458,6 @@
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
|
||||
@@ -5,11 +5,11 @@ const getGuests = async (req, res) => {
|
||||
const { search, limit = 50, offset = 0 } = req.query;
|
||||
let query = `
|
||||
SELECT g.*,
|
||||
r.room_id, rm.name_room,
|
||||
r.room_id, rm.room_number,
|
||||
r.check_in as current_check_in
|
||||
FROM guests g
|
||||
LEFT JOIN reservations r ON r.guest_id = g.id AND r.status = 'checked_in'
|
||||
LEFT JOIN rooms rm ON rm.id_room = r.room_id
|
||||
LEFT JOIN rooms rm ON rm.id = r.room_id
|
||||
`;
|
||||
const params = [];
|
||||
let paramIndex = 1;
|
||||
@@ -38,10 +38,10 @@ const getGuestById = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const guest = await pool.query(`
|
||||
SELECT g.*, r.room_id, rm.name_room, r.check_in as current_check_in, r.check_out as current_check_out
|
||||
SELECT g.*, r.room_id, rm.room_number, r.check_in as current_check_in, r.check_out as current_check_out
|
||||
FROM guests g
|
||||
LEFT JOIN reservations r ON r.guest_id = g.id AND r.status = 'checked_in'
|
||||
LEFT JOIN rooms rm ON rm.id_room = r.room_id
|
||||
LEFT JOIN rooms rm ON rm.id = r.room_id
|
||||
WHERE g.id = $1
|
||||
`, [id]);
|
||||
|
||||
@@ -92,9 +92,9 @@ const getGuestStays = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const result = await pool.query(`
|
||||
SELECT gs.*, rm.name_room, rm.bed_type
|
||||
SELECT gs.*, rm.room_number, rm.room_type
|
||||
FROM guest_stays gs
|
||||
LEFT JOIN rooms rm ON rm.id_room = gs.room_id
|
||||
LEFT JOIN rooms rm ON rm.id = gs.room_id
|
||||
WHERE gs.guest_id = $1
|
||||
ORDER BY gs.check_in DESC
|
||||
`, [id]);
|
||||
|
||||
@@ -4,12 +4,12 @@ const getTasks = async (req, res) => {
|
||||
try {
|
||||
const { status, priority, assigned_to } = req.query;
|
||||
let query = `
|
||||
SELECT ht.*, rm.name_room, rm.floor,
|
||||
SELECT ht.*, rm.room_number, rm.floor,
|
||||
CASE WHEN ht.assigned_to IS NOT NULL THEN
|
||||
(SELECT e.first_name || ' ' || e.last_name FROM employees e WHERE e.id_employee = ht.assigned_to)
|
||||
(SELECT e.first_name || ' ' || e.last_name FROM employees e WHERE e.id = ht.assigned_to)
|
||||
END as assigned_name
|
||||
FROM housekeeping_tasks ht
|
||||
LEFT JOIN rooms rm ON rm.id_room = ht.room_id
|
||||
LEFT JOIN rooms rm ON rm.id = ht.room_id
|
||||
WHERE 1=1
|
||||
`;
|
||||
const params = [];
|
||||
@@ -62,7 +62,7 @@ const updateTask = async (req, res) => {
|
||||
updates.status = 'completed';
|
||||
updates.completed_at = new Date();
|
||||
// Set room to available
|
||||
await pool.query("UPDATE rooms SET status = 'available' WHERE id_room = $1", [task.room_id]);
|
||||
await pool.query("UPDATE rooms SET status = 'available' WHERE id = $1", [task.room_id]);
|
||||
await pool.query(
|
||||
'INSERT INTO room_status_log (room_id, previous_status, new_status, changed_by) VALUES ($1, $2, $3, $4)',
|
||||
[task.room_id, 'cleaning', 'available', req.user?.user_id]
|
||||
@@ -91,10 +91,10 @@ const getStaff = async (req, res) => {
|
||||
// Get employees from housekeeping-related areas
|
||||
// Note: the employees table structure uses stored functions, so we query directly
|
||||
const result = await pool.query(`
|
||||
SELECT e.id_employee, e.first_name, e.last_name,
|
||||
(SELECT COUNT(*) FROM housekeeping_tasks ht WHERE ht.assigned_to = e.id_employee AND ht.status = 'in_progress') as active_tasks
|
||||
SELECT e.id, e.first_name, e.last_name,
|
||||
(SELECT COUNT(*) FROM housekeeping_tasks ht WHERE ht.assigned_to = e.id AND ht.status = 'in_progress') as active_tasks
|
||||
FROM employees e
|
||||
WHERE e.status_employee = true
|
||||
WHERE e.status = 'active'
|
||||
ORDER BY e.first_name
|
||||
LIMIT 50
|
||||
`);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const pool = require('../db/connection');
|
||||
const axios = require('axios');
|
||||
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
|
||||
const stripe = process.env.STRIPE_SECRET_KEY ? require('stripe')(process.env.STRIPE_SECRET_KEY) : null;
|
||||
const getFacturas = async (initialDate, finalDate) => {
|
||||
try {
|
||||
const response = await axios.get(process.env.FACTURAS_API_URL, {
|
||||
|
||||
@@ -53,11 +53,11 @@ const getRevenueReport = async (req, res) => {
|
||||
}
|
||||
|
||||
const result = await pool.query(`
|
||||
SELECT rm.bed_type as room_type, COALESCE(SUM(r.total_amount), 0) as revenue
|
||||
SELECT rm.room_type, COALESCE(SUM(r.total_amount), 0) as revenue
|
||||
FROM reservations r
|
||||
JOIN rooms rm ON rm.id_room = r.room_id
|
||||
JOIN rooms rm ON rm.id = r.room_id
|
||||
WHERE r.status = 'checked_out' AND r.check_out >= CURRENT_DATE - INTERVAL '${interval}'
|
||||
GROUP BY rm.bed_type
|
||||
GROUP BY rm.room_type
|
||||
ORDER BY revenue DESC
|
||||
`);
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ const getReservations = async (req, res) => {
|
||||
const { status, from_date, to_date, search } = req.query;
|
||||
let query = `
|
||||
SELECT r.*, g.first_name, g.last_name, g.phone, g.email,
|
||||
rm.name_room, rm.bed_type
|
||||
rm.room_number, rm.room_type
|
||||
FROM reservations r
|
||||
JOIN guests g ON g.id = r.guest_id
|
||||
LEFT JOIN rooms rm ON rm.id_room = r.room_id
|
||||
LEFT JOIN rooms rm ON rm.id = r.room_id
|
||||
WHERE 1=1
|
||||
`;
|
||||
const params = [];
|
||||
@@ -128,7 +128,7 @@ const updateReservationStatus = async (req, res) => {
|
||||
// Cascading side effects
|
||||
if (status === 'checked_in') {
|
||||
// Set room to occupied
|
||||
await pool.query("UPDATE rooms SET status = 'occupied' WHERE id_room = $1", [reservation.room_id]);
|
||||
await pool.query("UPDATE rooms SET status = 'occupied' WHERE id = $1", [reservation.room_id]);
|
||||
await pool.query(
|
||||
'INSERT INTO room_status_log (room_id, previous_status, new_status, changed_by) VALUES ($1, $2, $3, $4)',
|
||||
[reservation.room_id, 'available', 'occupied', userId]
|
||||
@@ -142,7 +142,7 @@ const updateReservationStatus = async (req, res) => {
|
||||
|
||||
if (status === 'checked_out') {
|
||||
// Set room to cleaning
|
||||
await pool.query("UPDATE rooms SET status = 'cleaning' WHERE id_room = $1", [reservation.room_id]);
|
||||
await pool.query("UPDATE rooms SET status = 'cleaning' WHERE id = $1", [reservation.room_id]);
|
||||
await pool.query(
|
||||
'INSERT INTO room_status_log (room_id, previous_status, new_status, changed_by) VALUES ($1, $2, $3, $4)',
|
||||
[reservation.room_id, 'occupied', 'cleaning', userId]
|
||||
@@ -162,7 +162,7 @@ const updateReservationStatus = async (req, res) => {
|
||||
if (status === 'cancelled') {
|
||||
// Free room if it was occupied
|
||||
if (reservation.status === 'checked_in') {
|
||||
await pool.query("UPDATE rooms SET status = 'available' WHERE id_room = $1", [reservation.room_id]);
|
||||
await pool.query("UPDATE rooms SET status = 'available' WHERE id = $1", [reservation.room_id]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ const getRoomsWithStatus = async (req, res) => {
|
||||
res.check_in,
|
||||
res.check_out
|
||||
FROM rooms r
|
||||
LEFT JOIN reservations res ON res.room_id = r.id_room AND res.status = 'checked_in'
|
||||
LEFT JOIN reservations res ON res.room_id = r.id AND res.status = 'checked_in'
|
||||
LEFT JOIN guests g ON g.id = res.guest_id
|
||||
ORDER BY r.floor, r.name_room
|
||||
ORDER BY r.floor, r.room_number
|
||||
`);
|
||||
res.json({ rooms: result.rows });
|
||||
} catch (error) {
|
||||
@@ -32,13 +32,13 @@ const updateRoomStatus = async (req, res) => {
|
||||
return res.status(400).json({ message: 'Estado invalido' });
|
||||
}
|
||||
|
||||
const current = await pool.query('SELECT status FROM rooms WHERE id_room = $1', [id]);
|
||||
const current = await pool.query('SELECT status FROM rooms WHERE id = $1', [id]);
|
||||
if (current.rows.length === 0) {
|
||||
return res.status(404).json({ message: 'Habitacion no encontrada' });
|
||||
}
|
||||
const previousStatus = current.rows[0].status;
|
||||
|
||||
await pool.query('UPDATE rooms SET status = $1 WHERE id_room = $2', [status, id]);
|
||||
await pool.query('UPDATE rooms SET status = $1 WHERE id = $2', [status, id]);
|
||||
|
||||
await pool.query(
|
||||
'INSERT INTO room_status_log (room_id, previous_status, new_status, changed_by) VALUES ($1, $2, $3, $4)',
|
||||
|
||||
@@ -4,10 +4,10 @@ const getOrders = async (req, res) => {
|
||||
try {
|
||||
const { status } = req.query;
|
||||
let query = `
|
||||
SELECT rso.*, rm.name_room, g.first_name || ' ' || g.last_name as guest_name,
|
||||
SELECT rso.*, rm.room_number, g.first_name || ' ' || g.last_name as guest_name,
|
||||
json_agg(json_build_object('id', oi.id, 'name', mi.name, 'quantity', oi.quantity, 'price', oi.price, 'notes', oi.notes)) as items
|
||||
FROM room_service_orders rso
|
||||
LEFT JOIN rooms rm ON rm.id_room = rso.room_id
|
||||
LEFT JOIN rooms rm ON rm.id = rso.room_id
|
||||
LEFT JOIN guests g ON g.id = rso.guest_id
|
||||
LEFT JOIN order_items oi ON oi.order_id = rso.id
|
||||
LEFT JOIN menu_items mi ON mi.id = oi.menu_item_id
|
||||
@@ -19,7 +19,7 @@ const getOrders = async (req, res) => {
|
||||
} else {
|
||||
query += " WHERE rso.status NOT IN ('delivered', 'cancelled')";
|
||||
}
|
||||
query += ' GROUP BY rso.id, rm.name_room, g.first_name, g.last_name ORDER BY rso.created_at DESC';
|
||||
query += ' GROUP BY rso.id, rm.room_number, g.first_name, g.last_name ORDER BY rso.created_at DESC';
|
||||
|
||||
const result = await pool.query(query, params);
|
||||
res.json({ orders: result.rows });
|
||||
|
||||
@@ -11,7 +11,7 @@ const getSchedules = async (req, res) => {
|
||||
let query = `
|
||||
SELECT es.*, e.first_name, e.last_name
|
||||
FROM employee_schedules es
|
||||
JOIN employees e ON e.id_employee = es.employee_id
|
||||
JOIN employees e ON e.id = es.employee_id
|
||||
WHERE es.schedule_date BETWEEN $1 AND $2
|
||||
`;
|
||||
const params = [week_start, weekEnd.toISOString().split('T')[0]];
|
||||
@@ -67,7 +67,7 @@ const getEmployeeSchedule = async (req, res) => {
|
||||
const getEmployeesForScheduling = async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(
|
||||
'SELECT id_employee, first_name, last_name FROM employees WHERE status_employee = true ORDER BY first_name LIMIT 100'
|
||||
"SELECT id, first_name, last_name FROM employees WHERE status = 'active' ORDER BY first_name LIMIT 100"
|
||||
);
|
||||
res.json({ employees: result.rows });
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user